зеркало из https://github.com/microsoft/jacdac-ts.git
fix: embed interface name cleanup (#300)
This commit is contained in:
Родитель
9c63509431
Коммит
40c5e978cd
|
@ -1,8 +1,8 @@
|
|||
import { delay } from "../jdom/utils"
|
||||
import { ISaveTextMessage } from "./protocol"
|
||||
import { ITransport } from "./transport"
|
||||
import { EmbedSaveTextMessage } from "./protocol"
|
||||
import { EmbedTransport } from "./transport"
|
||||
|
||||
export interface IFileStorage {
|
||||
export interface FileStorage {
|
||||
saveText(name: string, data: string): Promise<void>
|
||||
}
|
||||
|
||||
|
@ -17,7 +17,7 @@ export async function downloadUrl(url: string, name: string): Promise<void> {
|
|||
a.remove()
|
||||
}
|
||||
|
||||
export class BrowserFileStorage implements IFileStorage {
|
||||
export class BrowserFileStorage implements FileStorage {
|
||||
saveText(name: string, data: string, mimeType?: string): Promise<void> {
|
||||
if (!mimeType) {
|
||||
if (/\.(csv|txt)/i.test(name)) mimeType = "text/plain"
|
||||
|
@ -30,14 +30,14 @@ export class BrowserFileStorage implements IFileStorage {
|
|||
}
|
||||
}
|
||||
|
||||
export class HostedFileStorage implements IFileStorage {
|
||||
constructor(public readonly transport: ITransport) {}
|
||||
export class HostedFileStorage implements FileStorage {
|
||||
constructor(public readonly transport: EmbedTransport) {}
|
||||
saveText(name: string, data: string): Promise<void> {
|
||||
return this.transport
|
||||
.postMessage({
|
||||
type: "save-text",
|
||||
data: { name, data },
|
||||
} as ISaveTextMessage)
|
||||
} as EmbedSaveTextMessage)
|
||||
.then(resp => {})
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,51 +1,51 @@
|
|||
import { CHANGE } from "../jdom/constants"
|
||||
import { JDEventSource } from "../jdom/eventsource"
|
||||
import {
|
||||
IFile,
|
||||
IFileContent,
|
||||
IFileLoadMessage,
|
||||
IModelListMessage,
|
||||
EmbedFile,
|
||||
EmbedFileContent,
|
||||
EmbedFileLoadMessage,
|
||||
EmbedModelListMessage,
|
||||
} from "./protocol"
|
||||
import { ITransport } from "./transport"
|
||||
import { EmbedTransport } from "./transport"
|
||||
|
||||
export abstract class ModelStore extends JDEventSource {
|
||||
abstract models(): IFile[]
|
||||
abstract inputConfigurations(): IFile[]
|
||||
abstract loadFile(model: IFile): Promise<any>
|
||||
abstract models(): EmbedFile[]
|
||||
abstract inputConfigurations(): EmbedFile[]
|
||||
abstract loadFile(model: EmbedFile): Promise<any>
|
||||
}
|
||||
|
||||
export class HostedModelStore extends JDEventSource {
|
||||
private _models: IModelListMessage
|
||||
private _models: EmbedModelListMessage
|
||||
|
||||
constructor(public readonly transport: ITransport) {
|
||||
constructor(public readonly transport: EmbedTransport) {
|
||||
super()
|
||||
this.handleModelList = this.handleModelList.bind(this)
|
||||
|
||||
this.transport.onMessage("model-list", this.handleModelList)
|
||||
}
|
||||
|
||||
private handleModelList(msg: IModelListMessage) {
|
||||
private handleModelList(msg: EmbedModelListMessage) {
|
||||
this._models = msg
|
||||
this.emit(CHANGE)
|
||||
}
|
||||
|
||||
models(): IFile[] {
|
||||
models(): EmbedFile[] {
|
||||
return this._models?.data.models?.slice(0)
|
||||
}
|
||||
|
||||
inputConfigurations(): IFile[] {
|
||||
inputConfigurations(): EmbedFile[] {
|
||||
return this._models?.data.inputConfigurations?.slice(0)
|
||||
}
|
||||
|
||||
async loadFile(model: IFile): Promise<Blob> {
|
||||
async loadFile(model: EmbedFile): Promise<Blob> {
|
||||
const { path } = model
|
||||
const ack = await this.transport.postMessage({
|
||||
type: "file-load",
|
||||
requireAck: true,
|
||||
data: { path },
|
||||
} as IFileLoadMessage)
|
||||
} as EmbedFileLoadMessage)
|
||||
|
||||
const data = ack?.data?.data as IFileContent
|
||||
const data = ack?.data?.data as EmbedFileContent
|
||||
if (!data) return undefined
|
||||
|
||||
const base64 = data.mimetype === "application/octet-stream"
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
/** Jacdac IFrame Message protocol */
|
||||
export interface IMessage {
|
||||
export interface EmbedMessage {
|
||||
id?: string
|
||||
source: "jacdac"
|
||||
type: string
|
||||
data: any
|
||||
requireAck?: boolean
|
||||
}
|
||||
export interface IAckMessage extends IMessage {
|
||||
export interface EmbedAckMessage extends EmbedMessage {
|
||||
type: "ack"
|
||||
ackId?: string
|
||||
data: {
|
||||
|
@ -15,54 +15,60 @@ export interface IAckMessage extends IMessage {
|
|||
error?: any
|
||||
}
|
||||
}
|
||||
export type LogLevel = "error" | "warn" | "log" | "info" | "debug"
|
||||
export interface ILogMessage extends IMessage {
|
||||
export type EmbedLogLevel = "error" | "warn" | "log" | "info" | "debug"
|
||||
export interface EmbedLogMessage extends EmbedMessage {
|
||||
type: "log"
|
||||
data: {
|
||||
level?: LogLevel
|
||||
level?: EmbedLogLevel
|
||||
message: any
|
||||
}
|
||||
}
|
||||
export interface IThemeMessage extends IMessage {
|
||||
export interface EmbedThemeMessage extends EmbedMessage {
|
||||
type: "theme"
|
||||
data: {
|
||||
type: "light" | "dark"
|
||||
}
|
||||
}
|
||||
export type Status = "unknown" | "ready"
|
||||
export interface IStatusMessage extends IMessage {
|
||||
type: "status"
|
||||
export interface EmbedSpecsMessage extends EmbedMessage {
|
||||
type: "specs"
|
||||
data: {
|
||||
status: Status
|
||||
services?: jdspec.ServiceSpec[]
|
||||
}
|
||||
}
|
||||
export interface ISaveTextMessage extends IMessage {
|
||||
export type EmbedStatus = "unknown" | "ready"
|
||||
export interface EmbedStatusMessage extends EmbedMessage {
|
||||
type: "status"
|
||||
data: {
|
||||
status: EmbedStatus
|
||||
}
|
||||
}
|
||||
export interface EmbedSaveTextMessage extends EmbedMessage {
|
||||
type: "save-text"
|
||||
data: {
|
||||
name: string
|
||||
data: string
|
||||
}
|
||||
}
|
||||
export interface IFile {
|
||||
export interface EmbedFile {
|
||||
name: string
|
||||
path: string
|
||||
size: number
|
||||
mimetype: string
|
||||
}
|
||||
|
||||
export interface IFileContent {
|
||||
export interface EmbedFileContent {
|
||||
content: string
|
||||
mimetype: string
|
||||
}
|
||||
|
||||
export interface IModelListMessage extends IMessage {
|
||||
export interface EmbedModelListMessage extends EmbedMessage {
|
||||
type: "model-list"
|
||||
data: {
|
||||
models: IFile[]
|
||||
inputConfigurations: IFile[]
|
||||
models: EmbedFile[]
|
||||
inputConfigurations: EmbedFile[]
|
||||
}
|
||||
}
|
||||
export interface IFileLoadMessage extends IMessage {
|
||||
export interface EmbedFileLoadMessage extends EmbedMessage {
|
||||
type: "file-load"
|
||||
requireAck: true
|
||||
data: {
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
import { JDClient } from "../jdom/client"
|
||||
import { IAckMessage, IMessage, IStatusMessage } from "./protocol"
|
||||
import { EmbedAckMessage, EmbedMessage, EmbedStatusMessage } from "./protocol"
|
||||
|
||||
export interface ITransport {
|
||||
postMessage<TMessage extends IMessage, TResponse extends IMessage>(
|
||||
export interface EmbedTransport {
|
||||
postMessage<TMessage extends EmbedMessage, TResponse extends EmbedMessage>(
|
||||
msg: TMessage
|
||||
): Promise<TResponse>
|
||||
onMessage<TMessage extends IMessage>(
|
||||
onMessage<TMessage extends EmbedMessage>(
|
||||
type: string,
|
||||
handler: (msg: TMessage) => void
|
||||
): void
|
||||
|
@ -14,7 +14,7 @@ export interface ITransport {
|
|||
/**
|
||||
* @internal
|
||||
*/
|
||||
export class IFrameTransport extends JDClient implements ITransport {
|
||||
export class IFrameTransport extends JDClient implements EmbedTransport {
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
private readonly ackAwaiters: Record<string, (msg: any) => void> = {}
|
||||
|
||||
|
@ -41,23 +41,23 @@ export class IFrameTransport extends JDClient implements ITransport {
|
|||
data: {
|
||||
status: "ready",
|
||||
},
|
||||
} as IStatusMessage)
|
||||
} as EmbedStatusMessage)
|
||||
}
|
||||
|
||||
/**
|
||||
* Post message to client and awaits for ack if needed
|
||||
* @internal
|
||||
*/
|
||||
postMessage<TMessage extends IMessage, IAckMessage>(
|
||||
postMessage<TMessage extends EmbedMessage, AckMessage>(
|
||||
msg: TMessage
|
||||
): Promise<IAckMessage> {
|
||||
let p: Promise<IAckMessage>
|
||||
): Promise<AckMessage> {
|
||||
let p: Promise<AckMessage>
|
||||
|
||||
msg.id = "jd:" + Math.random()
|
||||
msg.source = "jacdac"
|
||||
|
||||
if (msg.requireAck) {
|
||||
p = new Promise<IAckMessage>(resolve => {
|
||||
p = new Promise<AckMessage>(resolve => {
|
||||
this.ackAwaiters[msg.id] = msg => {
|
||||
resolve(msg)
|
||||
}
|
||||
|
@ -68,7 +68,7 @@ export class IFrameTransport extends JDClient implements ITransport {
|
|||
return p || Promise.resolve(undefined)
|
||||
}
|
||||
|
||||
onMessage<TMessage extends IMessage>(
|
||||
onMessage<TMessage extends EmbedMessage>(
|
||||
type: string,
|
||||
handler: (msg: TMessage) => void
|
||||
): void {
|
||||
|
@ -78,12 +78,12 @@ export class IFrameTransport extends JDClient implements ITransport {
|
|||
private handleMessage(event: MessageEvent) {
|
||||
if (!this.isOriginValid(event)) return
|
||||
|
||||
const msg = event.data as IMessage
|
||||
const msg = event.data as EmbedMessage
|
||||
if (!msg || msg.source !== "jacdac") return
|
||||
|
||||
// handle acks separately
|
||||
if (msg.type === "ack") {
|
||||
const ack = msg as IAckMessage
|
||||
const ack = msg as EmbedAckMessage
|
||||
const awaiter = this.ackAwaiters[ack.ackId]
|
||||
delete this.ackAwaiters[ack.ackId]
|
||||
if (awaiter) awaiter(msg)
|
||||
|
|
|
@ -63,7 +63,13 @@ import { serviceClass } from "./pretty"
|
|||
import { JDNode } from "./node"
|
||||
import { FirmwareBlob, sendStayInBootloaderCommand } from "./flashing"
|
||||
import { JDService } from "./service"
|
||||
import { isConstRegister, isReading, isSensor } from "./spec"
|
||||
import {
|
||||
isConstRegister,
|
||||
isReading,
|
||||
isSensor,
|
||||
loadServiceSpecifications,
|
||||
serviceSpecifications,
|
||||
} from "./spec"
|
||||
import {
|
||||
LoggerPriority,
|
||||
LoggerReg,
|
||||
|
@ -740,7 +746,15 @@ export class JDBus extends JDNode {
|
|||
this._serviceProviders.forEach(host => (host.bus = undefined))
|
||||
this._serviceProviders = []
|
||||
}
|
||||
this.clearDevices()
|
||||
this.resetTime(timestamp)
|
||||
this.emit(CHANGE)
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears current device list and let's them repopulate
|
||||
*/
|
||||
private clearDevices() {
|
||||
// clear devices
|
||||
const devs = this._devices
|
||||
if (devs?.length) {
|
||||
|
@ -751,7 +765,6 @@ export class JDBus extends JDNode {
|
|||
this.emit(DEVICE_CHANGE, dev)
|
||||
})
|
||||
}
|
||||
this.resetTime(timestamp)
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1391,6 +1404,23 @@ ${dev
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the current list of service specifications
|
||||
*/
|
||||
get serviceSpecifications() {
|
||||
return serviceSpecifications()
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the current list of device and clears the bus
|
||||
* @param services
|
||||
*/
|
||||
setCustomServiceSpecifications(services: jdspec.ServiceSpec[]) {
|
||||
loadServiceSpecifications(services)
|
||||
this.clearDevices()
|
||||
this.emit(CHANGE)
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the virtual device created by this bus to handle pipes.
|
||||
* @category Services
|
||||
|
|
Загрузка…
Ссылка в новой задаче