@bardioc/app-sdk 0.5.0 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +86 -253
- package/dist/api/graph.d.ts +30 -0
- package/dist/api/graph.js +139 -0
- package/dist/api/os.d.ts +30 -0
- package/dist/api/os.js +48 -0
- package/dist/api/relay.d.ts +7 -0
- package/dist/api/relay.js +16 -0
- package/dist/api/request.d.ts +18 -0
- package/dist/api/request.js +12 -0
- package/dist/client.d.ts +104 -0
- package/dist/client.js +106 -0
- package/dist/contract.d.ts +294 -0
- package/dist/contract.js +150 -0
- package/dist/dev-idb.d.ts +10 -0
- package/dist/dev-idb.js +42 -0
- package/dist/dev-proxy.js +17 -3
- package/dist/dev.d.ts +16 -12
- package/dist/dev.js +101 -119
- package/dist/errors.d.ts +24 -25
- package/dist/errors.js +33 -48
- package/dist/index.d.ts +10 -7
- package/dist/index.js +2 -4
- package/dist/manifest.d.ts +10 -2
- package/dist/manifest.js +28 -24
- package/dist/protocol.d.ts +6 -29
- package/dist/protocol.js +3 -31
- package/dist/react.d.ts +21 -27
- package/dist/react.js +88 -212
- package/dist/serve.d.ts +26 -0
- package/dist/serve.js +64 -0
- package/dist/testing.d.ts +17 -0
- package/dist/testing.js +128 -0
- package/dist/types.d.ts +0 -250
- package/dist/vite.js +3 -0
- package/dist/wire.d.ts +46 -0
- package/dist/wire.js +138 -0
- package/package.json +12 -4
- package/dist/contract-matrix.d.ts +0 -148
- package/dist/contract-matrix.js +0 -150
- package/dist/host-bridge.d.ts +0 -3
- package/dist/host-bridge.js +0 -318
- package/dist/transports/backend-transport.d.ts +0 -24
- package/dist/transports/backend-transport.js +0 -54
- package/dist/transports/graph-transport.d.ts +0 -241
- package/dist/transports/graph-transport.js +0 -616
- package/dist/transports/os-transport.d.ts +0 -190
- package/dist/transports/os-transport.js +0 -444
package/dist/api/os.js
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { json } from './request.js';
|
|
2
|
+
const segment = encodeURIComponent;
|
|
3
|
+
/** The Bardioc OS API, called through the host. */
|
|
4
|
+
export function osApi(request) {
|
|
5
|
+
const unit = (id) => `/os/organization/units/${segment(id)}`;
|
|
6
|
+
const member = (id) => `/os/organization/members/${segment(id)}`;
|
|
7
|
+
const app = (id, suffix = '') => `/os/applications/${segment(id)}${suffix}`;
|
|
8
|
+
return {
|
|
9
|
+
profile: {
|
|
10
|
+
get: () => request({ path: '/os/me/profile' }),
|
|
11
|
+
getAvatar: () => request({ path: '/os/me/avatar' }),
|
|
12
|
+
setAvatar: (image) => request({
|
|
13
|
+
path: '/os/me/avatar',
|
|
14
|
+
method: 'POST',
|
|
15
|
+
body: image,
|
|
16
|
+
contentType: 'application/octet-stream',
|
|
17
|
+
}),
|
|
18
|
+
getInstances: () => request({ path: '/os/me/instances' }),
|
|
19
|
+
},
|
|
20
|
+
organization: {
|
|
21
|
+
getStructure: () => request({ path: '/os/organization/structure' }),
|
|
22
|
+
createUnit: (data) => request({ path: '/os/organization/units', ...json(data) }),
|
|
23
|
+
updateUnit: (id, data) => request({ path: unit(id), ...json(data, 'PATCH') }),
|
|
24
|
+
createMember: (data) => request({ path: '/os/organization/members', ...json(data) }),
|
|
25
|
+
updateMember: (id, data) => request({ path: member(id), ...json(data, 'PATCH') }),
|
|
26
|
+
deleteMember: (id) => request({ path: member(id), method: 'DELETE' }),
|
|
27
|
+
inviteMember: (id) => request({
|
|
28
|
+
path: `${member(id)}/invite`,
|
|
29
|
+
method: 'POST',
|
|
30
|
+
contentType: 'application/json',
|
|
31
|
+
}),
|
|
32
|
+
},
|
|
33
|
+
applications: {
|
|
34
|
+
list: () => request({ path: '/os/applications' }),
|
|
35
|
+
get: (id) => request({ path: app(id) }),
|
|
36
|
+
upload: (id, zip) => request({
|
|
37
|
+
path: app(id, '/upload'),
|
|
38
|
+
method: 'POST',
|
|
39
|
+
body: zip,
|
|
40
|
+
contentType: 'application/zip',
|
|
41
|
+
}),
|
|
42
|
+
download: (id) => request({ path: app(id, '/download') }),
|
|
43
|
+
getFiles: (id) => request({ path: app(id, '/files') }),
|
|
44
|
+
getFile: (id, path) => request({ path: app(id, `/files/${segment(path)}`) }),
|
|
45
|
+
getConfigurations: (id) => request({ path: app(id, '/configurations') }),
|
|
46
|
+
},
|
|
47
|
+
};
|
|
48
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { BffRequest } from '../contract.js';
|
|
2
|
+
import type { BffRequester } from './request.js';
|
|
3
|
+
/** An application's own backend, reached through the BFF relay; scoped unless told otherwise. */
|
|
4
|
+
export declare function relayApi(request: BffRequester, routeKey: string): {
|
|
5
|
+
request: <T = unknown>({ path, ...rest }: BffRequest) => Promise<T>;
|
|
6
|
+
};
|
|
7
|
+
export type RelayApi = ReturnType<typeof relayApi>;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { BardiocError } from '../errors.js';
|
|
2
|
+
// Mirrors the BFF's route key rule: one path segment, "." and ".." excluded.
|
|
3
|
+
const ROUTE_KEY = /^[A-Za-z0-9._-]+$/;
|
|
4
|
+
/** An application's own backend, reached through the BFF relay; scoped unless told otherwise. */
|
|
5
|
+
export function relayApi(request, routeKey) {
|
|
6
|
+
if (routeKey === '.' || routeKey === '..' || !ROUTE_KEY.test(routeKey)) {
|
|
7
|
+
throw new BardiocError('invalid', `Invalid relay route key "${routeKey}"`);
|
|
8
|
+
}
|
|
9
|
+
return {
|
|
10
|
+
request: ({ path, ...rest }) => request({
|
|
11
|
+
scopePolicy: 'required',
|
|
12
|
+
...rest,
|
|
13
|
+
path: `/relay/${routeKey}${path.startsWith('/') ? path : `/${path}`}`,
|
|
14
|
+
}),
|
|
15
|
+
};
|
|
16
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { BffRequest } from '../contract.js';
|
|
2
|
+
import type { TransportScopeOptions } from '../types.js';
|
|
3
|
+
export type BffRequester = <T>(request: BffRequest) => Promise<T>;
|
|
4
|
+
type QueryValue = string | number | boolean | undefined;
|
|
5
|
+
export declare function withQuery(path: string, params: Record<string, QueryValue>): string;
|
|
6
|
+
export declare const json: (body: unknown, method?: BffRequest["method"]) => {
|
|
7
|
+
readonly method: "GET" | "POST" | "PUT" | "PATCH" | "DELETE";
|
|
8
|
+
readonly body: unknown;
|
|
9
|
+
readonly contentType: "application/json";
|
|
10
|
+
};
|
|
11
|
+
export declare const scoped: ({ scopeId }?: TransportScopeOptions) => {
|
|
12
|
+
readonly scopeId: string;
|
|
13
|
+
readonly scopePolicy: "required";
|
|
14
|
+
} | {
|
|
15
|
+
readonly scopeId?: undefined;
|
|
16
|
+
readonly scopePolicy?: undefined;
|
|
17
|
+
};
|
|
18
|
+
export {};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export function withQuery(path, params) {
|
|
2
|
+
const query = new URLSearchParams();
|
|
3
|
+
for (const [key, value] of Object.entries(params)) {
|
|
4
|
+
if (value !== undefined && value !== '')
|
|
5
|
+
query.set(key, String(value));
|
|
6
|
+
}
|
|
7
|
+
const search = query.toString();
|
|
8
|
+
return search ? `${path}?${search}` : path;
|
|
9
|
+
}
|
|
10
|
+
export const json = (body, method = 'POST') => ({ method, body, contentType: 'application/json' });
|
|
11
|
+
// An explicit scope must hold; without one the host applies the window's instance.
|
|
12
|
+
export const scoped = ({ scopeId } = {}) => scopeId ? { scopeId, scopePolicy: 'required' } : {};
|
package/dist/client.d.ts
ADDED
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import { type AppRecord, type AppUpload, type BffRequest, type Command, type Context, type GraphEvent, type IdbEntry, type MenuRoot, type NotifyLevel, type Shortcut } from './contract.js';
|
|
2
|
+
declare function open(port: MessagePort, initial: Context): {
|
|
3
|
+
readonly context: Context;
|
|
4
|
+
onContextChange: (listener: (context: Context) => void) => () => void;
|
|
5
|
+
ui: {
|
|
6
|
+
notify: (message: string, level?: NotifyLevel) => Promise<void>;
|
|
7
|
+
setCommands: (commands: Command[]) => Promise<void>;
|
|
8
|
+
setMenu: (menu: MenuRoot[] | null) => Promise<void>;
|
|
9
|
+
setActiveTab: (activeTab: string | null) => Promise<void>;
|
|
10
|
+
shortcut: (shortcut: Shortcut) => Promise<void>;
|
|
11
|
+
/** Runs `run` when the host invokes the command; the returned function unregisters it. */
|
|
12
|
+
onCommand: (id: string, run: () => unknown) => () => void;
|
|
13
|
+
};
|
|
14
|
+
bff: {
|
|
15
|
+
request: <T = unknown>(bffRequest: BffRequest, options?: {
|
|
16
|
+
signal?: AbortSignal;
|
|
17
|
+
}) => Promise<T>;
|
|
18
|
+
};
|
|
19
|
+
graph: {
|
|
20
|
+
get: <T = import("./types.js").GraphNodeRaw>(id: string, options?: import("./types.js").GetNodeOptions) => Promise<T>;
|
|
21
|
+
getMany: <T = import("./types.js").GraphNodeRaw>(ids: string[], options?: import("./types.js").GetNodeOptions) => Promise<(T | undefined)[]>;
|
|
22
|
+
getByXid: <T = import("./types.js").GraphNodeRaw>(xid: string, options?: import("./types.js").GetNodeOptions) => Promise<T>;
|
|
23
|
+
query: <T = import("./types.js").GraphNodeRaw>(lucene: string, options?: import("./types.js").QueryOptions) => Promise<T[]>;
|
|
24
|
+
gremlin: <T = unknown>(rootId: string, query: string, options?: import("./types.js").GremlinOptions) => Promise<T[]>;
|
|
25
|
+
combined: <T = unknown>(elasticsearchQuery: string, gremlinQuery: string, options?: import("./types.js").CombinedQueryOptions) => Promise<T[]>;
|
|
26
|
+
create: <T = import("./types.js").GraphNodeRaw>(type: string, data: Record<string, unknown>, options?: import("./types.js").MutationOptions) => Promise<T>;
|
|
27
|
+
update: <T = import("./types.js").GraphNodeRaw>(id: string, data: Record<string, unknown>, options?: import("./types.js").MutationOptions) => Promise<T>;
|
|
28
|
+
delete: (id: string, options?: import("./types.js").DeleteOptions) => Promise<void>;
|
|
29
|
+
connect: <T = import("./types.js").GraphEdgeRaw>(from: string, to: string, type: string, options?: import("./types.js").MutationOptions) => Promise<T>;
|
|
30
|
+
history: (id: string, options?: import("./types.js").HistoryOptions) => Promise<import("./types.js").HistoryEntry[]>;
|
|
31
|
+
batch: {
|
|
32
|
+
delete: (ids: string[], options?: import("./types.js").DeleteOptions) => Promise<import("./types.js").BatchResult>;
|
|
33
|
+
};
|
|
34
|
+
timeseries: {
|
|
35
|
+
get: (id: string, options?: import("./types.js").TimeseriesOptions) => Promise<import("./types.js").TimeseriesValue[]>;
|
|
36
|
+
add: (id: string, values: import("./types.js").TimeseriesValue[], options?: import("./types.js").TransportScopeOptions) => Promise<void>;
|
|
37
|
+
query: (options: import("./types.js").TimeseriesQueryOptions) => Promise<import("./types.js").TimeseriesValue[]>;
|
|
38
|
+
history: (id: string, timestamp: number, options?: import("./types.js").TimeseriesHistoryOptions) => Promise<import("./types.js").TimeseriesHistory>;
|
|
39
|
+
};
|
|
40
|
+
content: {
|
|
41
|
+
set: (id: string, data: Blob, contentType: string, options?: import("./types.js").TransportScopeOptions) => Promise<string>;
|
|
42
|
+
get: (id: string, contentId: string, options?: import("./types.js").TransportScopeOptions) => Promise<Blob>;
|
|
43
|
+
};
|
|
44
|
+
};
|
|
45
|
+
os: {
|
|
46
|
+
profile: {
|
|
47
|
+
get: () => Promise<import("./types.js").UserProfile>;
|
|
48
|
+
getAvatar: () => Promise<Blob>;
|
|
49
|
+
setAvatar: (image: Blob) => Promise<void>;
|
|
50
|
+
getInstances: () => Promise<import("./types.js").InstanceList>;
|
|
51
|
+
};
|
|
52
|
+
organization: {
|
|
53
|
+
getStructure: () => Promise<import("./types.js").OrgStructure>;
|
|
54
|
+
createUnit: (data: import("./types.js").CreateUnitInput) => Promise<import("./types.js").OrgUnit>;
|
|
55
|
+
updateUnit: (id: string, data: import("./types.js").UpdateUnitInput) => Promise<import("./types.js").OrgUnit>;
|
|
56
|
+
createMember: (data: import("./types.js").CreateMemberInput) => Promise<import("./types.js").OrgMember>;
|
|
57
|
+
updateMember: (id: string, data: import("./types.js").UpdateMemberInput) => Promise<import("./types.js").OrgMember>;
|
|
58
|
+
deleteMember: (id: string) => Promise<void>;
|
|
59
|
+
inviteMember: (id: string) => Promise<void>;
|
|
60
|
+
};
|
|
61
|
+
applications: {
|
|
62
|
+
list: () => Promise<import("./types.js").Application[]>;
|
|
63
|
+
get: (id: string) => Promise<import("./types.js").Application>;
|
|
64
|
+
upload: (id: string, zip: Blob) => Promise<void>;
|
|
65
|
+
download: (id: string) => Promise<Blob>;
|
|
66
|
+
getFiles: (id: string) => Promise<import("./types.js").FileEntry[]>;
|
|
67
|
+
getFile: (id: string, path: string) => Promise<string>;
|
|
68
|
+
getConfigurations: (id: string) => Promise<import("./types.js").Configuration[]>;
|
|
69
|
+
};
|
|
70
|
+
};
|
|
71
|
+
relay: (routeKey: string) => {
|
|
72
|
+
request: <T = unknown>({ path, ...rest }: BffRequest) => Promise<T>;
|
|
73
|
+
};
|
|
74
|
+
idb: (store: string) => {
|
|
75
|
+
get: <T = unknown>(key: string) => Promise<IdbEntry<T> | null>;
|
|
76
|
+
put: (key: string, value: unknown) => Promise<void>;
|
|
77
|
+
delete: (key: string) => Promise<void>;
|
|
78
|
+
query: <T = unknown>(options?: {
|
|
79
|
+
prefix?: string;
|
|
80
|
+
limit?: number;
|
|
81
|
+
}) => Promise<IdbEntry<T>[]>;
|
|
82
|
+
};
|
|
83
|
+
events: {
|
|
84
|
+
/** Streams graph events of `types`; resolves to the function that ends the stream. */
|
|
85
|
+
graph: (filter: {
|
|
86
|
+
types: string[];
|
|
87
|
+
}, onEvent: (event: GraphEvent) => void) => Promise<() => void>;
|
|
88
|
+
};
|
|
89
|
+
apps: {
|
|
90
|
+
list: () => Promise<import("./contract.js").InstalledApp[]>;
|
|
91
|
+
get: (id: string) => Promise<import("./contract.js").InstalledApp>;
|
|
92
|
+
save: (app: AppRecord) => Promise<import("./contract.js").InstalledApp>;
|
|
93
|
+
delete: (id: string) => Promise<void>;
|
|
94
|
+
/** The file contents are transferred to the host and unusable here afterwards. */
|
|
95
|
+
upload: (upload: AppUpload) => Promise<import("./contract.js").UploadResult>;
|
|
96
|
+
launch: (id: string) => Promise<{
|
|
97
|
+
windowId: string | null;
|
|
98
|
+
}>;
|
|
99
|
+
};
|
|
100
|
+
};
|
|
101
|
+
export type Bardioc = ReturnType<typeof open>;
|
|
102
|
+
/** Connects this document to its host; every call shares the one connection. */
|
|
103
|
+
export declare function connect(): Promise<Bardioc>;
|
|
104
|
+
export {};
|
package/dist/client.js
ADDED
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import { graphApi } from './api/graph.js';
|
|
2
|
+
import { osApi } from './api/os.js';
|
|
3
|
+
import { relayApi } from './api/relay.js';
|
|
4
|
+
import { APP_METHODS, PROTOCOL_VERSION, } from './contract.js';
|
|
5
|
+
import { BardiocError } from './errors.js';
|
|
6
|
+
import { isHandshake, Peer, readStream, READY } from './wire.js';
|
|
7
|
+
const CONNECT_TIMEOUT_MS = 10_000;
|
|
8
|
+
function handshake() {
|
|
9
|
+
const host = window.parent;
|
|
10
|
+
return new Promise((resolve, reject) => {
|
|
11
|
+
const settle = (done) => {
|
|
12
|
+
clearTimeout(timer);
|
|
13
|
+
window.removeEventListener('message', onMessage);
|
|
14
|
+
done();
|
|
15
|
+
};
|
|
16
|
+
const timer = setTimeout(() => settle(() => reject(new BardiocError('unavailable', 'No Bardioc host answered'))), CONNECT_TIMEOUT_MS);
|
|
17
|
+
const onMessage = ({ source, data, ports: [port] }) => {
|
|
18
|
+
if (source !== host || !isHandshake(data))
|
|
19
|
+
return;
|
|
20
|
+
if (data.bardioc === 'connect' && port) {
|
|
21
|
+
settle(() => resolve({ port, context: data.context }));
|
|
22
|
+
}
|
|
23
|
+
else if (data.bardioc === 'reject') {
|
|
24
|
+
const message = `The host speaks protocol ${data.protocol}, this SDK ${PROTOCOL_VERSION}`;
|
|
25
|
+
settle(() => reject(new BardiocError('protocol', message)));
|
|
26
|
+
}
|
|
27
|
+
};
|
|
28
|
+
window.addEventListener('message', onMessage);
|
|
29
|
+
host.postMessage(READY, '*');
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
function open(port, initial) {
|
|
33
|
+
let context = initial;
|
|
34
|
+
const commands = new Map();
|
|
35
|
+
const runCommand = async (params) => {
|
|
36
|
+
const { id } = params;
|
|
37
|
+
const run = commands.get(id);
|
|
38
|
+
if (!run)
|
|
39
|
+
throw new BardiocError('not_found', `Command ${id} is not registered`);
|
|
40
|
+
await run();
|
|
41
|
+
};
|
|
42
|
+
const peer = new Peer(port, new Map([['ui.command', runCommand]]));
|
|
43
|
+
peer.on('context.changed', next => (context = next));
|
|
44
|
+
const call = (method, params, options = {}) => peer.call(method, params, {
|
|
45
|
+
timeoutMs: APP_METHODS[method].timeoutMs,
|
|
46
|
+
...options,
|
|
47
|
+
});
|
|
48
|
+
const request = (bffRequest, options) => call('bff.request', bffRequest, options);
|
|
49
|
+
return {
|
|
50
|
+
get context() {
|
|
51
|
+
return context;
|
|
52
|
+
},
|
|
53
|
+
onContextChange: (listener) => peer.on('context.changed', next => listener(next)),
|
|
54
|
+
ui: {
|
|
55
|
+
notify: (message, level = 'info') => call('ui.notify', { message, level }),
|
|
56
|
+
setCommands: (commands) => call('ui.setCommands', { commands }),
|
|
57
|
+
setMenu: (menu) => call('ui.setMenu', { menu }),
|
|
58
|
+
setActiveTab: (activeTab) => call('ui.setActiveTab', { activeTab }),
|
|
59
|
+
shortcut: (shortcut) => call('ui.shortcut', shortcut),
|
|
60
|
+
/** Runs `run` when the host invokes the command; the returned function unregisters it. */
|
|
61
|
+
onCommand: (id, run) => {
|
|
62
|
+
commands.set(id, run);
|
|
63
|
+
return () => {
|
|
64
|
+
if (commands.get(id) === run)
|
|
65
|
+
commands.delete(id);
|
|
66
|
+
};
|
|
67
|
+
},
|
|
68
|
+
},
|
|
69
|
+
bff: { request },
|
|
70
|
+
graph: graphApi(request),
|
|
71
|
+
os: osApi(request),
|
|
72
|
+
relay: (routeKey) => relayApi(request, routeKey),
|
|
73
|
+
idb: (store) => ({
|
|
74
|
+
get: (key) => call('idb.get', { store, key }),
|
|
75
|
+
put: (key, value) => call('idb.put', { store, key, value }),
|
|
76
|
+
delete: (key) => call('idb.delete', { store, key }),
|
|
77
|
+
query: (options = {}) => call('idb.query', { store, ...options }),
|
|
78
|
+
}),
|
|
79
|
+
events: {
|
|
80
|
+
/** Streams graph events of `types`; resolves to the function that ends the stream. */
|
|
81
|
+
graph: async (filter, onEvent) => {
|
|
82
|
+
const { timeoutMs } = APP_METHODS['events.graph'];
|
|
83
|
+
const stream = (await peer.call('events.graph', filter, { timeoutMs }));
|
|
84
|
+
return readStream(stream, event => onEvent(event));
|
|
85
|
+
},
|
|
86
|
+
},
|
|
87
|
+
apps: {
|
|
88
|
+
list: () => call('apps.list', undefined),
|
|
89
|
+
get: (id) => call('apps.get', { id }),
|
|
90
|
+
save: (app) => call('apps.save', app),
|
|
91
|
+
delete: (id) => call('apps.delete', { id }),
|
|
92
|
+
/** The file contents are transferred to the host and unusable here afterwards. */
|
|
93
|
+
upload: (upload) => call('apps.upload', upload, { transfer: upload.files.map(file => file.content) }),
|
|
94
|
+
launch: (id) => call('apps.launch', { id }),
|
|
95
|
+
},
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
let connecting;
|
|
99
|
+
/** Connects this document to its host; every call shares the one connection. */
|
|
100
|
+
export function connect() {
|
|
101
|
+
connecting ??= handshake().then(({ port, context }) => open(port, context), (error) => {
|
|
102
|
+
connecting = undefined;
|
|
103
|
+
throw error;
|
|
104
|
+
});
|
|
105
|
+
return connecting;
|
|
106
|
+
}
|
|
@@ -0,0 +1,294 @@
|
|
|
1
|
+
import * as z from 'zod/mini';
|
|
2
|
+
export declare const PROTOCOL_VERSION = 1;
|
|
3
|
+
export interface CallMethod<I extends z.ZodMiniType = z.ZodMiniType, O = unknown> {
|
|
4
|
+
readonly kind: 'call';
|
|
5
|
+
readonly input: I;
|
|
6
|
+
readonly timeoutMs: number;
|
|
7
|
+
readonly output?: O;
|
|
8
|
+
}
|
|
9
|
+
export interface StreamMethod<I extends z.ZodMiniType = z.ZodMiniType, O = unknown> {
|
|
10
|
+
readonly kind: 'stream';
|
|
11
|
+
readonly input: I;
|
|
12
|
+
readonly timeoutMs: number;
|
|
13
|
+
readonly output?: O;
|
|
14
|
+
}
|
|
15
|
+
export type Method = CallMethod | StreamMethod;
|
|
16
|
+
declare const Command: z.ZodMiniObject<{
|
|
17
|
+
id: z.ZodMiniString<string>;
|
|
18
|
+
title: z.ZodMiniOptional<z.ZodMiniString<string>>;
|
|
19
|
+
disabled: z.ZodMiniOptional<z.ZodMiniBoolean<boolean>>;
|
|
20
|
+
checked: z.ZodMiniOptional<z.ZodMiniBoolean<boolean>>;
|
|
21
|
+
}, z.core.$strict>;
|
|
22
|
+
export type MenuItem = {
|
|
23
|
+
type: 'command';
|
|
24
|
+
commandId: string;
|
|
25
|
+
label?: string;
|
|
26
|
+
leftIcon?: string;
|
|
27
|
+
separatorAbove?: boolean;
|
|
28
|
+
shortcut?: string;
|
|
29
|
+
variant?: 'default' | 'destructive';
|
|
30
|
+
} | {
|
|
31
|
+
type: 'submenu';
|
|
32
|
+
label: string;
|
|
33
|
+
leftIcon?: string;
|
|
34
|
+
separatorAbove?: boolean;
|
|
35
|
+
contentWidth?: string;
|
|
36
|
+
items: MenuItem[];
|
|
37
|
+
};
|
|
38
|
+
declare const MenuRoot: z.ZodMiniObject<{
|
|
39
|
+
label: z.ZodMiniString<string>;
|
|
40
|
+
kind: z.ZodMiniOptional<z.ZodMiniEnum<{
|
|
41
|
+
app: "app";
|
|
42
|
+
menu: "menu";
|
|
43
|
+
}>>;
|
|
44
|
+
leftIcon: z.ZodMiniOptional<z.ZodMiniString<string>>;
|
|
45
|
+
contentWidth: z.ZodMiniOptional<z.ZodMiniString<string>>;
|
|
46
|
+
items: z.ZodMiniArray<z.ZodMiniType<MenuItem, unknown, z.core.$ZodTypeInternals<MenuItem, unknown>>>;
|
|
47
|
+
}, z.core.$strict>;
|
|
48
|
+
declare const Notify: z.ZodMiniObject<{
|
|
49
|
+
message: z.ZodMiniString<string>;
|
|
50
|
+
level: z.ZodMiniEnum<{
|
|
51
|
+
success: "success";
|
|
52
|
+
error: "error";
|
|
53
|
+
info: "info";
|
|
54
|
+
warning: "warning";
|
|
55
|
+
}>;
|
|
56
|
+
}, z.core.$strict>;
|
|
57
|
+
declare const Shortcut: z.ZodMiniObject<{
|
|
58
|
+
code: z.ZodMiniString<string>;
|
|
59
|
+
ctrlKey: z.ZodMiniBoolean<boolean>;
|
|
60
|
+
metaKey: z.ZodMiniBoolean<boolean>;
|
|
61
|
+
altKey: z.ZodMiniBoolean<boolean>;
|
|
62
|
+
shiftKey: z.ZodMiniBoolean<boolean>;
|
|
63
|
+
}, z.core.$strict>;
|
|
64
|
+
declare const BffRequest: z.ZodMiniObject<{
|
|
65
|
+
path: z.ZodMiniString<string>;
|
|
66
|
+
method: z.ZodMiniOptional<z.ZodMiniEnum<{
|
|
67
|
+
GET: "GET";
|
|
68
|
+
POST: "POST";
|
|
69
|
+
PUT: "PUT";
|
|
70
|
+
PATCH: "PATCH";
|
|
71
|
+
DELETE: "DELETE";
|
|
72
|
+
}>>;
|
|
73
|
+
body: z.ZodMiniOptional<z.ZodMiniUnknown>;
|
|
74
|
+
contentType: z.ZodMiniOptional<z.ZodMiniString<string>>;
|
|
75
|
+
scopeId: z.ZodMiniOptional<z.ZodMiniString<string>>;
|
|
76
|
+
scopePolicy: z.ZodMiniOptional<z.ZodMiniEnum<{
|
|
77
|
+
none: "none";
|
|
78
|
+
optional: "optional";
|
|
79
|
+
required: "required";
|
|
80
|
+
}>>;
|
|
81
|
+
}, z.core.$strict>;
|
|
82
|
+
declare const AppRecord: z.ZodMiniObject<{
|
|
83
|
+
id: z.ZodMiniString<string>;
|
|
84
|
+
name: z.ZodMiniString<string>;
|
|
85
|
+
version: z.ZodMiniString<string>;
|
|
86
|
+
launchUrl: z.ZodMiniString<string>;
|
|
87
|
+
source: z.ZodMiniEnum<{
|
|
88
|
+
uploaded: "uploaded";
|
|
89
|
+
dev: "dev";
|
|
90
|
+
}>;
|
|
91
|
+
description: z.ZodMiniOptional<z.ZodMiniString<string>>;
|
|
92
|
+
icon: z.ZodMiniOptional<z.ZodMiniString<string>>;
|
|
93
|
+
appId: z.ZodMiniOptional<z.ZodMiniString<string>>;
|
|
94
|
+
bundleSize: z.ZodMiniOptional<z.ZodMiniNumberFormat>;
|
|
95
|
+
fileCount: z.ZodMiniOptional<z.ZodMiniNumberFormat>;
|
|
96
|
+
}, z.core.$strict>;
|
|
97
|
+
declare const AppUpload: z.ZodMiniObject<{
|
|
98
|
+
alias: z.ZodMiniString<string>;
|
|
99
|
+
name: z.ZodMiniString<string>;
|
|
100
|
+
files: z.ZodMiniArray<z.ZodMiniObject<{
|
|
101
|
+
path: z.ZodMiniString<string>;
|
|
102
|
+
content: z.ZodMiniCustom<ArrayBuffer, ArrayBuffer>;
|
|
103
|
+
}, z.core.$strict>>;
|
|
104
|
+
appId: z.ZodMiniOptional<z.ZodMiniString<string>>;
|
|
105
|
+
source: z.ZodMiniOptional<z.ZodMiniEnum<{
|
|
106
|
+
uploaded: "uploaded";
|
|
107
|
+
dev: "dev";
|
|
108
|
+
}>>;
|
|
109
|
+
}, z.core.$strict>;
|
|
110
|
+
export type Command = z.infer<typeof Command>;
|
|
111
|
+
export type MenuRoot = z.infer<typeof MenuRoot>;
|
|
112
|
+
export type Shortcut = z.infer<typeof Shortcut>;
|
|
113
|
+
export type NotifyLevel = z.infer<typeof Notify>['level'];
|
|
114
|
+
export type BffRequest = z.infer<typeof BffRequest>;
|
|
115
|
+
export type AppRecord = z.infer<typeof AppRecord>;
|
|
116
|
+
export type AppUpload = z.infer<typeof AppUpload>;
|
|
117
|
+
export interface OsConfig {
|
|
118
|
+
theme: 'light' | 'dark';
|
|
119
|
+
language: string;
|
|
120
|
+
systemSize?: string;
|
|
121
|
+
tabId: string;
|
|
122
|
+
windowId: string;
|
|
123
|
+
instanceId: string | null;
|
|
124
|
+
}
|
|
125
|
+
/** What the host tells an app when it connects, and again whenever it changes. */
|
|
126
|
+
export interface Context {
|
|
127
|
+
appId: string;
|
|
128
|
+
host: 'os' | 'dev';
|
|
129
|
+
osConfig: OsConfig;
|
|
130
|
+
}
|
|
131
|
+
export interface IdbEntry<T = unknown> {
|
|
132
|
+
key: string;
|
|
133
|
+
value: T;
|
|
134
|
+
updatedAt: number;
|
|
135
|
+
}
|
|
136
|
+
export declare const GRAPH_EVENT_TYPES: readonly ["CREATE", "REPLACE", "UPDATE", "CONNECT", "DISCONNECT", "DELETE", "WRITE_TIMESERIES"];
|
|
137
|
+
export interface GraphEvent {
|
|
138
|
+
id: string;
|
|
139
|
+
type: (typeof GRAPH_EVENT_TYPES)[number];
|
|
140
|
+
timestamp: number;
|
|
141
|
+
nanotime?: number;
|
|
142
|
+
body?: Record<string, unknown>;
|
|
143
|
+
metadata?: Record<string, unknown>;
|
|
144
|
+
}
|
|
145
|
+
export interface InstalledApp extends AppRecord {
|
|
146
|
+
installedAt: number;
|
|
147
|
+
updatedAt?: number;
|
|
148
|
+
}
|
|
149
|
+
export interface UploadResult {
|
|
150
|
+
appId: string;
|
|
151
|
+
name: string;
|
|
152
|
+
entryUrl: string;
|
|
153
|
+
runtime: 'iframe-v1';
|
|
154
|
+
storedFiles: number;
|
|
155
|
+
totalSize: number;
|
|
156
|
+
}
|
|
157
|
+
/** Methods an app calls on its host. */
|
|
158
|
+
export declare const APP_METHODS: {
|
|
159
|
+
readonly 'ui.notify': CallMethod<z.ZodMiniObject<{
|
|
160
|
+
message: z.ZodMiniString<string>;
|
|
161
|
+
level: z.ZodMiniEnum<{
|
|
162
|
+
success: "success";
|
|
163
|
+
error: "error";
|
|
164
|
+
info: "info";
|
|
165
|
+
warning: "warning";
|
|
166
|
+
}>;
|
|
167
|
+
}, z.core.$strict>, void>;
|
|
168
|
+
readonly 'ui.setCommands': CallMethod<z.ZodMiniObject<{
|
|
169
|
+
commands: z.ZodMiniArray<z.ZodMiniObject<{
|
|
170
|
+
id: z.ZodMiniString<string>;
|
|
171
|
+
title: z.ZodMiniOptional<z.ZodMiniString<string>>;
|
|
172
|
+
disabled: z.ZodMiniOptional<z.ZodMiniBoolean<boolean>>;
|
|
173
|
+
checked: z.ZodMiniOptional<z.ZodMiniBoolean<boolean>>;
|
|
174
|
+
}, z.core.$strict>>;
|
|
175
|
+
}, z.core.$strict>, void>;
|
|
176
|
+
readonly 'ui.setMenu': CallMethod<z.ZodMiniObject<{
|
|
177
|
+
menu: z.ZodMiniNullable<z.ZodMiniArray<z.ZodMiniObject<{
|
|
178
|
+
label: z.ZodMiniString<string>;
|
|
179
|
+
kind: z.ZodMiniOptional<z.ZodMiniEnum<{
|
|
180
|
+
app: "app";
|
|
181
|
+
menu: "menu";
|
|
182
|
+
}>>;
|
|
183
|
+
leftIcon: z.ZodMiniOptional<z.ZodMiniString<string>>;
|
|
184
|
+
contentWidth: z.ZodMiniOptional<z.ZodMiniString<string>>;
|
|
185
|
+
items: z.ZodMiniArray<z.ZodMiniType<MenuItem, unknown, z.core.$ZodTypeInternals<MenuItem, unknown>>>;
|
|
186
|
+
}, z.core.$strict>>>;
|
|
187
|
+
}, z.core.$strict>, void>;
|
|
188
|
+
readonly 'ui.setActiveTab': CallMethod<z.ZodMiniObject<{
|
|
189
|
+
activeTab: z.ZodMiniNullable<z.ZodMiniString<string>>;
|
|
190
|
+
}, z.core.$strict>, void>;
|
|
191
|
+
readonly 'ui.shortcut': CallMethod<z.ZodMiniObject<{
|
|
192
|
+
code: z.ZodMiniString<string>;
|
|
193
|
+
ctrlKey: z.ZodMiniBoolean<boolean>;
|
|
194
|
+
metaKey: z.ZodMiniBoolean<boolean>;
|
|
195
|
+
altKey: z.ZodMiniBoolean<boolean>;
|
|
196
|
+
shiftKey: z.ZodMiniBoolean<boolean>;
|
|
197
|
+
}, z.core.$strict>, void>;
|
|
198
|
+
readonly 'bff.request': CallMethod<z.ZodMiniObject<{
|
|
199
|
+
path: z.ZodMiniString<string>;
|
|
200
|
+
method: z.ZodMiniOptional<z.ZodMiniEnum<{
|
|
201
|
+
GET: "GET";
|
|
202
|
+
POST: "POST";
|
|
203
|
+
PUT: "PUT";
|
|
204
|
+
PATCH: "PATCH";
|
|
205
|
+
DELETE: "DELETE";
|
|
206
|
+
}>>;
|
|
207
|
+
body: z.ZodMiniOptional<z.ZodMiniUnknown>;
|
|
208
|
+
contentType: z.ZodMiniOptional<z.ZodMiniString<string>>;
|
|
209
|
+
scopeId: z.ZodMiniOptional<z.ZodMiniString<string>>;
|
|
210
|
+
scopePolicy: z.ZodMiniOptional<z.ZodMiniEnum<{
|
|
211
|
+
none: "none";
|
|
212
|
+
optional: "optional";
|
|
213
|
+
required: "required";
|
|
214
|
+
}>>;
|
|
215
|
+
}, z.core.$strict>, unknown>;
|
|
216
|
+
readonly 'events.graph': StreamMethod<z.ZodMiniObject<{
|
|
217
|
+
types: z.ZodMiniArray<z.ZodMiniString<string>>;
|
|
218
|
+
}, z.core.$strict>, GraphEvent>;
|
|
219
|
+
readonly 'idb.get': CallMethod<z.ZodMiniObject<{
|
|
220
|
+
store: z.ZodMiniString<string>;
|
|
221
|
+
key: z.ZodMiniString<string>;
|
|
222
|
+
}, z.core.$strict>, IdbEntry<unknown> | null>;
|
|
223
|
+
readonly 'idb.put': CallMethod<z.ZodMiniObject<{
|
|
224
|
+
store: z.ZodMiniString<string>;
|
|
225
|
+
key: z.ZodMiniString<string>;
|
|
226
|
+
value: z.ZodMiniUnknown;
|
|
227
|
+
}, z.core.$strict>, void>;
|
|
228
|
+
readonly 'idb.delete': CallMethod<z.ZodMiniObject<{
|
|
229
|
+
store: z.ZodMiniString<string>;
|
|
230
|
+
key: z.ZodMiniString<string>;
|
|
231
|
+
}, z.core.$strict>, void>;
|
|
232
|
+
readonly 'idb.query': CallMethod<z.ZodMiniObject<{
|
|
233
|
+
store: z.ZodMiniString<string>;
|
|
234
|
+
prefix: z.ZodMiniOptional<z.ZodMiniString<string>>;
|
|
235
|
+
limit: z.ZodMiniOptional<z.ZodMiniNumberFormat>;
|
|
236
|
+
}, z.core.$strict>, IdbEntry<unknown>[]>;
|
|
237
|
+
readonly 'apps.list': CallMethod<z.ZodMiniUndefined, InstalledApp[]>;
|
|
238
|
+
readonly 'apps.get': CallMethod<z.ZodMiniObject<{
|
|
239
|
+
id: z.ZodMiniString<string>;
|
|
240
|
+
}, z.core.$strict>, InstalledApp>;
|
|
241
|
+
readonly 'apps.save': CallMethod<z.ZodMiniObject<{
|
|
242
|
+
id: z.ZodMiniString<string>;
|
|
243
|
+
name: z.ZodMiniString<string>;
|
|
244
|
+
version: z.ZodMiniString<string>;
|
|
245
|
+
launchUrl: z.ZodMiniString<string>;
|
|
246
|
+
source: z.ZodMiniEnum<{
|
|
247
|
+
uploaded: "uploaded";
|
|
248
|
+
dev: "dev";
|
|
249
|
+
}>;
|
|
250
|
+
description: z.ZodMiniOptional<z.ZodMiniString<string>>;
|
|
251
|
+
icon: z.ZodMiniOptional<z.ZodMiniString<string>>;
|
|
252
|
+
appId: z.ZodMiniOptional<z.ZodMiniString<string>>;
|
|
253
|
+
bundleSize: z.ZodMiniOptional<z.ZodMiniNumberFormat>;
|
|
254
|
+
fileCount: z.ZodMiniOptional<z.ZodMiniNumberFormat>;
|
|
255
|
+
}, z.core.$strict>, InstalledApp>;
|
|
256
|
+
readonly 'apps.delete': CallMethod<z.ZodMiniObject<{
|
|
257
|
+
id: z.ZodMiniString<string>;
|
|
258
|
+
}, z.core.$strict>, void>;
|
|
259
|
+
readonly 'apps.upload': CallMethod<z.ZodMiniObject<{
|
|
260
|
+
alias: z.ZodMiniString<string>;
|
|
261
|
+
name: z.ZodMiniString<string>;
|
|
262
|
+
files: z.ZodMiniArray<z.ZodMiniObject<{
|
|
263
|
+
path: z.ZodMiniString<string>;
|
|
264
|
+
content: z.ZodMiniCustom<ArrayBuffer, ArrayBuffer>;
|
|
265
|
+
}, z.core.$strict>>;
|
|
266
|
+
appId: z.ZodMiniOptional<z.ZodMiniString<string>>;
|
|
267
|
+
source: z.ZodMiniOptional<z.ZodMiniEnum<{
|
|
268
|
+
uploaded: "uploaded";
|
|
269
|
+
dev: "dev";
|
|
270
|
+
}>>;
|
|
271
|
+
}, z.core.$strict>, UploadResult>;
|
|
272
|
+
readonly 'apps.launch': CallMethod<z.ZodMiniObject<{
|
|
273
|
+
id: z.ZodMiniString<string>;
|
|
274
|
+
}, z.core.$strict>, {
|
|
275
|
+
windowId: string | null;
|
|
276
|
+
}>;
|
|
277
|
+
};
|
|
278
|
+
/** Methods a host calls on its app. */
|
|
279
|
+
export declare const HOST_METHODS: {
|
|
280
|
+
readonly 'ui.command': CallMethod<z.ZodMiniObject<{
|
|
281
|
+
id: z.ZodMiniString<string>;
|
|
282
|
+
}, z.core.$strict>, void>;
|
|
283
|
+
};
|
|
284
|
+
/** Events a host pushes to its app. */
|
|
285
|
+
export interface HostEvents {
|
|
286
|
+
'context.changed': Context;
|
|
287
|
+
}
|
|
288
|
+
export type AppMethods = typeof APP_METHODS;
|
|
289
|
+
export type HostMethods = typeof HOST_METHODS;
|
|
290
|
+
export type Params<M extends Method> = z.infer<M['input']>;
|
|
291
|
+
export type Result<M extends Method> = Exclude<M['output'], undefined>;
|
|
292
|
+
/** The BFF event-stream filter matching any of `types`. */
|
|
293
|
+
export declare function graphEventFilter(types: readonly string[]): string;
|
|
294
|
+
export {};
|