@ekrooh/bare 0.4.0 → 0.5.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.
@@ -1,9 +1,11 @@
1
- import { ErrorCode, definePlugin, err, ok } from "./index.mjs";
1
+ import { g as ErrorCode, m as ok, p as err, r as definePlugin } from "./messages-BbpF3wNH.mjs";
2
2
  import { discoverySpecs } from "./plugins-discovery-events.mjs";
3
3
  import { healthSpecs } from "./plugins-health-events.mjs";
4
+ import { logsSpecs } from "./plugins-logs-events.mjs";
4
5
  import { mediaSpecs } from "./plugins-media-events.mjs";
5
6
  import { permissionSpecs } from "./plugins-permissions-events.mjs";
6
- //#region plugins/discovery/plugin.ts
7
+ import crypto from "bare-crypto";
8
+ // plugins/discovery/plugin.ts
7
9
  function mergeCapabilityRows(a, b) {
8
10
  const map = /* @__PURE__ */ new Map();
9
11
  for (const row of [...a, ...b]) {
@@ -40,8 +42,7 @@ function createDiscoveryPlugin(deps) {
40
42
  } }
41
43
  });
42
44
  }
43
- //#endregion
44
- //#region plugins/health/plugin.ts
45
+ // plugins/health/plugin.ts
45
46
  function createHealthPlugin() {
46
47
  return definePlugin("core.health", healthSpecs, {
47
48
  capabilities: ["health"],
@@ -61,10 +62,31 @@ function createHealthPlugin() {
61
62
  }
62
63
  });
63
64
  }
64
- //#endregion
65
- //#region plugins/media/plugin.ts
65
+ const LOGS_VIEW_DEFAULT_TAIL = 20;
66
+ function createLogsPlugin(deps) {
67
+ return definePlugin("core.logs", logsSpecs, {
68
+ capabilities: ["logs"],
69
+ invoke: {
70
+ view: (args) => {
71
+ const tail = args?.tail === void 0 ? LOGS_VIEW_DEFAULT_TAIL : Math.max(0, Math.min(args.tail, 100));
72
+ return ok({ entries: deps.store.view({
73
+ tail,
74
+ level: args?.level,
75
+ source: args?.source
76
+ }) });
77
+ },
78
+ clear: () => ok({ cleared: deps.store.clear() })
79
+ }
80
+ });
81
+ }
82
+ // plugins/media/plugin.ts
83
+ /** Most media mounts are consumed once and then linger. Cap how many stay
84
+ * mounted at once and evict the least-recently-used so picked/captured files
85
+ * do not accumulate on the loopback server for the whole session. */
86
+ const MEDIA_MOUNT_CAP = 4;
66
87
  function newRequestId() {
67
- return `${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 10)}`;
88
+ const rand = crypto.randomBytes(16).toString("base64").replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
89
+ return `${Date.now().toString(36)}-${rand}`;
68
90
  }
69
91
  /**
70
92
  * `vendor.media` — reference plugin demonstrating out-of-band binary transfer.
@@ -74,6 +96,17 @@ function newRequestId() {
74
96
  * is identical on every runtime.
75
97
  */
76
98
  function createMediaPlugin(deps) {
99
+ const mounted = /* @__PURE__ */ new Map();
100
+ const mountMedia = (id, path) => {
101
+ deps.staticServer.mount(`/media/${id}`, path);
102
+ mounted.set(id, path);
103
+ while (mounted.size > MEDIA_MOUNT_CAP) {
104
+ const oldestId = mounted.keys().next().value;
105
+ const oldestPath = mounted.get(oldestId);
106
+ mounted.delete(oldestId);
107
+ if (oldestPath !== void 0) deps.staticServer.unmount(`/media/${oldestId}`);
108
+ }
109
+ };
77
110
  const serve = async (event, args) => {
78
111
  const host = await deps.invokeOnHost({
79
112
  type: "INVOKE_REQUEST",
@@ -87,12 +120,9 @@ function createMediaPlugin(deps) {
87
120
  const path = host.result?.path;
88
121
  if (!path) return err(ErrorCode.HOST_ERROR, `Host returned no path for ${event}`);
89
122
  const id = `${args?.kind ?? "media"}-${newRequestId()}`;
90
- deps.staticServer.mount(`/media/${id}`, path);
123
+ mountMedia(id, path);
91
124
  const url = await deps.staticServer.url(`/media/${id}`);
92
- return ok({
93
- url,
94
- path
95
- });
125
+ return ok({ url });
96
126
  };
97
127
  return definePlugin("vendor.media", mediaSpecs, {
98
128
  capabilities: ["media"],
@@ -102,8 +132,7 @@ function createMediaPlugin(deps) {
102
132
  }
103
133
  });
104
134
  }
105
- //#endregion
106
- //#region plugins/permissions/plugin.ts
135
+ // plugins/permissions/plugin.ts
107
136
  /**
108
137
  * Declares host-only permission events. Handlers are registered on the Android host
109
138
  * via {@code HostPluginRegistry}; the worklet delegates invokes here over IPC.
@@ -111,15 +140,14 @@ function createMediaPlugin(deps) {
111
140
  function createPermissionsPluginStub() {
112
141
  return definePlugin("core.permissions", permissionSpecs, { capabilities: ["permissions"] });
113
142
  }
114
- //#endregion
115
- //#region plugins/index.ts
143
+ // plugins/index.ts
116
144
  function createDefaultPlugins(deps) {
117
145
  return [
118
146
  createHealthPlugin(),
119
147
  createDiscoveryPlugin(deps),
120
148
  createPermissionsPluginStub(),
121
- createMediaPlugin(deps)
149
+ createMediaPlugin(deps),
150
+ createLogsPlugin(deps)
122
151
  ];
123
152
  }
124
- //#endregion
125
153
  export { createDefaultPlugins as t };
@@ -1,10 +1,9 @@
1
- import { A as CapabilityDescriptor, B as InvokeEnvelope } from "./index-DjulYFJL.mjs";
2
- //#region plugins/discovery/events.d.ts
3
- type DiscoveryListResult = {
1
+ import { F as CapabilityDescriptor, G as InvokeEnvelope } from "./index-BkwUzwVt.mjs";
2
+ export type DiscoveryListResult = {
4
3
  schemaVersion: 1;
5
4
  capabilities: CapabilityDescriptor[];
6
5
  };
7
- declare const discoverySpecs: {
6
+ export declare const discoverySpecs: {
8
7
  readonly list: {
9
8
  readonly pluginId: 'core.discovery';
10
9
  readonly name: 'discovery.list';
@@ -12,10 +11,8 @@ declare const discoverySpecs: {
12
11
  readonly result: DiscoveryListResult;
13
12
  };
14
13
  };
15
- declare const discoveryEvents: {
14
+ export declare const discoveryEvents: {
16
15
  discovery: {
17
16
  list(): InvokeEnvelope<"discovery.list", Record<string, never>, DiscoveryListResult>;
18
17
  };
19
- };
20
- //#endregion
21
- export { DiscoveryListResult, discoveryEvents, discoverySpecs };
18
+ };
@@ -1,5 +1,5 @@
1
- import { invokeEvent } from "./index.mjs";
2
- //#region plugins/discovery/events.ts
1
+ import { a as invokeEvent } from "./messages-BbpF3wNH.mjs";
2
+ // plugins/discovery/events.ts
3
3
  const discoverySpecs = { list: {
4
4
  pluginId: "core.discovery",
5
5
  name: "discovery.list",
@@ -9,5 +9,4 @@ const discoverySpecs = { list: {
9
9
  const discoveryEvents = { discovery: { list() {
10
10
  return invokeEvent(discoverySpecs.list, {});
11
11
  } } };
12
- //#endregion
13
12
  export { discoveryEvents, discoverySpecs };
@@ -1,6 +1,5 @@
1
- import { B as InvokeEnvelope } from "./index-DjulYFJL.mjs";
2
- //#region plugins/health/events.d.ts
3
- declare const healthSpecs: {
1
+ import { G as InvokeEnvelope } from "./index-BkwUzwVt.mjs";
2
+ export declare const healthSpecs: {
4
3
  readonly ping: {
5
4
  readonly pluginId: 'core.health';
6
5
  readonly name: 'health.ping';
@@ -33,7 +32,7 @@ declare const healthSpecs: {
33
32
  };
34
33
  };
35
34
  };
36
- declare const healthEvents: {
35
+ export declare const healthEvents: {
37
36
  health: {
38
37
  ping(message?: string): InvokeEnvelope<'health.ping', {
39
38
  message?: string;
@@ -52,6 +51,4 @@ declare const healthEvents: {
52
51
  ts: number;
53
52
  }>;
54
53
  };
55
- };
56
- //#endregion
57
- export { healthEvents, healthSpecs };
54
+ };
@@ -1,5 +1,5 @@
1
- import { invokeEvent } from "./index.mjs";
2
- //#region plugins/health/events.ts
1
+ import { a as invokeEvent } from "./messages-BbpF3wNH.mjs";
2
+ // plugins/health/events.ts
3
3
  const healthSpecs = {
4
4
  ping: {
5
5
  pluginId: "core.health",
@@ -31,5 +31,4 @@ const healthEvents = { health: {
31
31
  return invokeEvent(healthSpecs.roundtrip, {});
32
32
  }
33
33
  } };
34
- //#endregion
35
34
  export { healthEvents, healthSpecs };
@@ -0,0 +1,34 @@
1
+ import { G as InvokeEnvelope, i as LogSource, n as LogEntry, r as LogLevel } from "./index-BkwUzwVt.mjs";
2
+ export type LogsViewArgs = {
3
+ /** Most-recent N matching entries. Defaults to a small window. */
4
+ tail?: number;
5
+ level?: LogLevel;
6
+ source?: LogSource;
7
+ };
8
+ export type LogsViewResult = {
9
+ entries: LogEntry[];
10
+ };
11
+ export type LogsClearResult = {
12
+ cleared: number;
13
+ };
14
+ export declare const logsSpecs: {
15
+ readonly view: {
16
+ readonly pluginId: 'core.logs';
17
+ readonly name: 'logs.view';
18
+ readonly args: LogsViewArgs;
19
+ readonly result: LogsViewResult;
20
+ };
21
+ readonly clear: {
22
+ readonly pluginId: 'core.logs';
23
+ readonly name: 'logs.clear';
24
+ readonly args: Record<string, never>;
25
+ readonly result: LogsClearResult;
26
+ };
27
+ };
28
+ export declare const logEvents: {
29
+ logs: {
30
+ view(options?: LogsViewArgs): InvokeEnvelope<'logs.view', LogsViewArgs, LogsViewResult>;
31
+ clear(): InvokeEnvelope<'logs.clear', Record<string, never>, LogsClearResult>;
32
+ };
33
+ };
34
+ export type { LogEntry, LogLevel, LogSource };
@@ -0,0 +1,25 @@
1
+ import { a as invokeEvent } from "./messages-BbpF3wNH.mjs";
2
+ // plugins/logs/events.ts
3
+ const logsSpecs = {
4
+ view: {
5
+ pluginId: "core.logs",
6
+ name: "logs.view",
7
+ args: {},
8
+ result: {}
9
+ },
10
+ clear: {
11
+ pluginId: "core.logs",
12
+ name: "logs.clear",
13
+ args: {},
14
+ result: {}
15
+ }
16
+ };
17
+ const logEvents = { logs: {
18
+ view(options = {}) {
19
+ return invokeEvent(logsSpecs.view, options);
20
+ },
21
+ clear() {
22
+ return invokeEvent(logsSpecs.clear, {});
23
+ }
24
+ } };
25
+ export { logEvents, logsSpecs };
@@ -1,13 +1,10 @@
1
- import { B as InvokeEnvelope } from "./index-DjulYFJL.mjs";
2
- //#region plugins/media/events.d.ts
3
- type MediaKind = 'image' | 'video';
4
- type MediaResult = {
1
+ import { G as InvokeEnvelope } from "./index-BkwUzwVt.mjs";
2
+ export type MediaKind = 'image' | 'video';
3
+ export type MediaResult = {
5
4
  /** URL served by the worklet's loopback HTTP server (no bytes on the wire). */
6
5
  url: string;
7
- /** Absolute filesystem path of the picked file on the host. */
8
- path: string;
9
6
  };
10
- declare const mediaSpecs: {
7
+ export declare const mediaSpecs: {
11
8
  readonly pick: {
12
9
  readonly pluginId: 'vendor.media';
13
10
  readonly name: 'media.pick';
@@ -25,7 +22,7 @@ declare const mediaSpecs: {
25
22
  readonly result: MediaResult;
26
23
  };
27
24
  };
28
- declare const mediaEvents: {
25
+ export declare const mediaEvents: {
29
26
  media: {
30
27
  pick(kind?: MediaKind): InvokeEnvelope<'media.pick', {
31
28
  kind?: MediaKind;
@@ -34,6 +31,4 @@ declare const mediaEvents: {
34
31
  kind?: MediaKind;
35
32
  }, MediaResult>;
36
33
  };
37
- };
38
- //#endregion
39
- export { MediaKind, MediaResult, mediaEvents, mediaSpecs };
34
+ };
@@ -1,5 +1,5 @@
1
- import { invokeEvent } from "./index.mjs";
2
- //#region plugins/media/events.ts
1
+ import { a as invokeEvent } from "./messages-BbpF3wNH.mjs";
2
+ // plugins/media/events.ts
3
3
  const MEDIA_INVOKE_TIMEOUT_MS = 3e5;
4
4
  const mediaSpecs = {
5
5
  pick: {
@@ -23,5 +23,4 @@ const mediaEvents = { media: {
23
23
  return invokeEvent(mediaSpecs.capture, { kind }, null, MEDIA_INVOKE_TIMEOUT_MS);
24
24
  }
25
25
  } };
26
- //#endregion
27
26
  export { mediaEvents, mediaSpecs };
@@ -1,13 +1,12 @@
1
- import { B as InvokeEnvelope } from "./index-DjulYFJL.mjs";
2
- //#region plugins/permissions/events.d.ts
1
+ import { G as InvokeEnvelope } from "./index-BkwUzwVt.mjs";
3
2
  /** Canonical permission ids. Hosts map each to their platform equivalent. */
4
- type PermissionId = 'storage' | 'camera';
5
- type PermissionStatus = 'granted' | 'denied' | 'notDetermined' | 'unsupported';
6
- type PermissionResult = {
3
+ export type PermissionId = 'storage' | 'camera';
4
+ export type PermissionStatus = 'granted' | 'denied' | 'notDetermined' | 'unsupported';
5
+ export type PermissionResult = {
7
6
  permission: PermissionId;
8
7
  status: PermissionStatus;
9
8
  };
10
- declare const permissionSpecs: {
9
+ export declare const permissionSpecs: {
11
10
  readonly request: {
12
11
  readonly pluginId: 'core.permissions';
13
12
  readonly name: 'permissions.request';
@@ -25,7 +24,7 @@ declare const permissionSpecs: {
25
24
  readonly result: PermissionResult;
26
25
  };
27
26
  };
28
- declare const permissionEvents: {
27
+ export declare const permissionEvents: {
29
28
  permissions: {
30
29
  request(permission: PermissionId): InvokeEnvelope<'permissions.request', {
31
30
  permission: PermissionId;
@@ -34,6 +33,4 @@ declare const permissionEvents: {
34
33
  permission: PermissionId;
35
34
  }, PermissionResult>;
36
35
  };
37
- };
38
- //#endregion
39
- export { PermissionId, PermissionResult, PermissionStatus, permissionEvents, permissionSpecs };
36
+ };
@@ -1,5 +1,5 @@
1
- import { invokeEvent } from "./index.mjs";
2
- //#region plugins/permissions/events.ts
1
+ import { a as invokeEvent } from "./messages-BbpF3wNH.mjs";
2
+ // plugins/permissions/events.ts
3
3
  const permissionSpecs = {
4
4
  request: {
5
5
  pluginId: "core.permissions",
@@ -22,5 +22,4 @@ const permissionEvents = { permissions: {
22
22
  return invokeEvent(permissionSpecs.status, { permission });
23
23
  }
24
24
  } };
25
- //#endregion
26
25
  export { permissionEvents, permissionSpecs };
@@ -1,6 +1,5 @@
1
- import { A as CapabilityDescriptor, G as PluginInvokeRequestHeader, K as PluginInvokeResponseHeader, Y as RuntimeTarget, q as PluginManifest } from "./index-DjulYFJL.mjs";
2
- import { n as LoopbackServer } from "./static-file-server-DY9EKEVf.mjs";
3
- //#region plugins/discovery/plugin.d.ts
1
+ import { F as CapabilityDescriptor, Q as PluginManifest, X as PluginInvokeRequestHeader, Z as PluginInvokeResponseHeader, a as LogStore, et as RuntimeTarget } from "./index-BkwUzwVt.mjs";
2
+ import { n as LoopbackServer } from "./static-file-server-C8pIX1JD.mjs";
4
3
  type DiscoveryPluginDeps = {
5
4
  listBareCapabilities: () => Array<{
6
5
  pluginId: string;
@@ -10,17 +9,16 @@ type DiscoveryPluginDeps = {
10
9
  }>;
11
10
  queryHostCapabilities: () => Promise<CapabilityDescriptor[]>;
12
11
  };
13
- //#endregion
14
- //#region plugins/media/plugin.d.ts
12
+ type LogsPluginDeps = {
13
+ /** Shared ring buffer fed by the worklet capture seam and the ingest route. */
14
+ store: LogStore;
15
+ };
15
16
  type MediaPluginDeps = {
16
17
  /** Worklet-side loopback server exposing picked files to the web layer. */
17
18
  staticServer: LoopbackServer;
18
19
  /** Delegates the native pick/capture to the host (`HOST_INVOKE_REQUEST`). */
19
20
  invokeOnHost: (header: PluginInvokeRequestHeader, payload: Uint8Array) => Promise<PluginInvokeResponseHeader | null>;
20
21
  };
21
- //#endregion
22
- //#region plugins/index.d.ts
23
- type DefaultPluginsDeps = DiscoveryPluginDeps & MediaPluginDeps;
24
- declare function createDefaultPlugins(deps: DefaultPluginsDeps): PluginManifest[];
25
- //#endregion
26
- export { DefaultPluginsDeps, type DiscoveryPluginDeps, type MediaPluginDeps, createDefaultPlugins };
22
+ export type DefaultPluginsDeps = DiscoveryPluginDeps & MediaPluginDeps & LogsPluginDeps;
23
+ export declare function createDefaultPlugins(deps: DefaultPluginsDeps): PluginManifest[];
24
+ export type { DiscoveryPluginDeps, LogsPluginDeps, MediaPluginDeps };
package/dist/plugins.mjs CHANGED
@@ -1,2 +1 @@
1
- import { t as createDefaultPlugins } from "./plugins-1KweEBct.mjs";
2
- export { createDefaultPlugins };
1
+ export { t as createDefaultPlugins } from "./plugins-DZu_NWVp.mjs";
@@ -1,6 +1,5 @@
1
- import { A as CapabilityDescriptor, G as PluginInvokeRequestHeader, K as PluginInvokeResponseHeader, V as MessageHeader, d as MessageProtocol, q as PluginManifest, t as BareRuntimeContext, v as createPluginRegistry, y as createPluginRouter } from "./index-DjulYFJL.mjs";
2
- import { i as createLoopbackServer, n as LoopbackServer, r as collectRequestBody, t as LoopbackRouteHandler } from "./static-file-server-DY9EKEVf.mjs";
3
- //#region core/messages/host-ipc.d.ts
1
+ import { C as createPluginRegistry, F as CapabilityDescriptor, K as MessageHeader, Q as PluginManifest, X as PluginInvokeRequestHeader, Z as PluginInvokeResponseHeader, g as MessageProtocol, o as BareRuntimeContext, tt as WireMessage, w as createPluginRouter } from "./index-BkwUzwVt.mjs";
2
+ import { i as createLoopbackServer, n as LoopbackServer, r as collectRequestBody, t as LoopbackRouteHandler } from "./static-file-server-C8pIX1JD.mjs";
4
3
  type BareIpcLike = {
5
4
  write(data: Uint8Array | Buffer | string): boolean;
6
5
  };
@@ -8,28 +7,23 @@ declare function createHostIpcBridge(config: {
8
7
  ipc: BareIpcLike;
9
8
  protocol: MessageProtocol;
10
9
  }): {
10
+ tryConsumeDownstream: (parsed: WireMessage) => boolean;
11
11
  tryConsumeDownstreamFromHost(raw: Uint8Array | ArrayBuffer | Buffer): boolean;
12
12
  queryCapabilities(timeoutMs?: number): Promise<CapabilityDescriptor[]>;
13
13
  invokeOnHost(header: PluginInvokeRequestHeader, payload: Uint8Array, timeoutMs?: number): Promise<PluginInvokeResponseHeader | null>;
14
14
  };
15
- //#endregion
16
- //#region core/server/websocket-server.d.ts
17
- /** Envelope encoder bound to a loopback server's connected protocol socket —
18
- * the server-initiated (backend → web) push seam. */
19
15
  type LoopbackPush = (header: MessageHeader, payload?: Uint8Array | ArrayBuffer | null) => boolean;
20
16
  /** Builds the push seam for the server's connected protocol socket: encodes a
21
17
  * `DISPATCH`-style envelope and writes it, mirroring how `attachWebSocketProtocol`
22
18
  * writes responses. Returns false when no socket is connected. */
23
- declare function createLoopbackPush(server: LoopbackServer, protocol: MessageProtocol): LoopbackPush;
19
+ export declare function createLoopbackPush(server: LoopbackServer, protocol: MessageProtocol): LoopbackPush;
24
20
  /**
25
21
  * Attaches the framed-protocol socket to the unified loopback server. The
26
22
  * server owns the WebSocket upgrade (origin check, cookie/token auth, single
27
23
  * client, idle timeout); this layer only routes decoded envelopes through the
28
24
  * plugin router and writes responses back as raw frames.
29
25
  */
30
- declare function attachWebSocketProtocol(server: LoopbackServer, context: BareRuntimeContext): void;
31
- //#endregion
32
- //#region core/lib/get-ipc.d.ts
26
+ export declare function attachWebSocketProtocol(server: LoopbackServer, context: BareRuntimeContext): void;
33
27
  /**
34
28
  * @fileoverview Bare IPC provider for Android (BareKit) and Sidecar (Bare.IPC)
35
29
  */
@@ -44,9 +38,7 @@ interface BareIPC extends NodeJS.EventEmitter {
44
38
  * In BareKit (Android), it uses BareKit.IPC.
45
39
  * In Bare (Sidecar), it uses Bare.IPC.
46
40
  */
47
- declare function getIPC(): BareIPC;
48
- //#endregion
49
- //#region core/runtime.d.ts
41
+ export declare function getIPC(): BareIPC;
50
42
  /** Resolves the host-provided worklet configuration from `start(...)`
51
43
  * arguments. On-device hosts pass `["<webAssets>", "<storage>", "<cache>"]`
52
44
  * (three existing directories, in that order), landing at `Bare.argv[0..2]`;
@@ -55,7 +47,7 @@ declare function getIPC(): BareIPC;
55
47
  * file). Falls back to the labeled CLI token syntax (see `resolveCliConfig`)
56
48
  * when the positional shape doesn't match, so the same entry works for both
57
49
  * device and dev runs. */
58
- declare function resolveWorkletConfig(): WorkletRuntimeOptions;
50
+ export declare function resolveWorkletConfig(): WorkletRuntimeOptions;
59
51
  /**
60
52
  * Parses the dev/CLI labeled-token configuration from bare CLI arguments:
61
53
  * `webassets=<dir>`, `storage=<dir>`, `cache=<dir>`, `host=<addr>`,
@@ -68,8 +60,8 @@ declare function resolveWorkletConfig(): WorkletRuntimeOptions;
68
60
  * ephemeral), `auth: false`, `port: 8080`, each overridable by a token. When
69
61
  * no labeled tokens are present it returns `{}` (plain dev defaults).
70
62
  */
71
- declare function resolveCliConfig(argv?: readonly string[]): WorkletRuntimeOptions;
72
- type WorkletRuntimeOptions = {
63
+ export declare function resolveCliConfig(argv?: readonly string[]): WorkletRuntimeOptions;
64
+ export type WorkletRuntimeOptions = {
73
65
  /** Directory to serve at `/` (the built web app). */
74
66
  webAssets?: string;
75
67
  /** Durable app-sandbox directory: `handoff.json` + the p2p corestore. */
@@ -83,6 +75,11 @@ type WorkletRuntimeOptions = {
83
75
  port?: number;
84
76
  /** Require the per-session token/cookie. Defaults to on in device mode. */
85
77
  auth?: boolean;
78
+ /** Write the credentials to `<storage>/handoff.json` for the host to read
79
+ * (auth on only). Defaults to true; a host that receives them over its own
80
+ * channel (the desktop host reads them from a pipe) sets false so the
81
+ * session token never touches disk. */
82
+ handoffFile?: boolean;
86
83
  /** Explicit device-mode override. Defaults to on whenever `storage` is set
87
84
  * (the on-device 3-arg contract); `resolveCliConfig` resolves it to false so
88
85
  * a dev backend keeps auth off + fixed port even with a storage dir. */
@@ -92,14 +89,37 @@ type WorkletRuntimeOptions = {
92
89
  plugins?: PluginManifest[];
93
90
  /** Idle timeout (ms) after which an authenticated WebSocket is dropped. */
94
91
  wsIdleTimeoutMs?: number;
92
+ /** Dead-peer timeout (ms): a protocol socket that answers no ping within it
93
+ * is destroyed, freeing the slot. Defaults to 10s. */
94
+ wsDeadPeerTimeoutMs?: number;
95
+ /** Minimum gap (ms) before an accepted protocol socket may be replaced by a
96
+ * new authenticated one. Defaults to 1s. */
97
+ wsReplaceMinIntervalMs?: number;
98
+ /** Bytes queued behind a protocol socket whose reader stopped reading before
99
+ * server pushes are dropped (newest first). Defaults to 2 MiB. */
100
+ wsMaxQueuedBytes?: number;
101
+ /** Ring capacity for the `core.logs` capture store (retention knob; the
102
+ * rotating file sink is a consumer/app decision). Defaults to 500. */
103
+ logsCapacity?: number;
104
+ /** Global cap on calls routed at once; calls over it fail with a
105
+ * `TRANSPORT_ERROR`. Defaults to 64. */
106
+ maxInflight?: number;
107
+ /** Plugin ids whose calls must run one at a time, in arrival order. All
108
+ * other plugins run concurrently, so one slow call never blocks the rest. */
109
+ serialPlugins?: readonly string[];
110
+ /** Lowest level the `core.logs` capture store records (`debug` | `info` |
111
+ * `warn` | `error`). Lower-level console calls still reach stdout. Defaults
112
+ * to `debug` (record everything); raise it to stop routine debug traces
113
+ * from evicting warnings out of a small ring. */
114
+ logsMinLevel?: 'debug' | 'info' | 'warn' | 'error';
95
115
  };
96
- type WorkletRuntimeConfig = {
116
+ export type WorkletRuntimeConfig = {
97
117
  webAssets?: string;
98
118
  storage?: string;
99
119
  cache?: string;
100
120
  deviceMode: boolean;
101
121
  };
102
- interface WorkletRuntime {
122
+ export interface WorkletRuntime {
103
123
  protocol: MessageProtocol;
104
124
  pluginRegistry: ReturnType<typeof createPluginRegistry>;
105
125
  pluginRouter: ReturnType<typeof createPluginRouter>;
@@ -112,6 +132,7 @@ interface WorkletRuntime {
112
132
  origin: string;
113
133
  port: number;
114
134
  token: string;
135
+ bootstrap: string;
115
136
  }>;
116
137
  close(cb?: (err?: Error | null) => void): void;
117
138
  }
@@ -121,6 +142,5 @@ interface WorkletRuntime {
121
142
  * N of them and a consumer worklet entry can be just "register plugins +
122
143
  * wire p2p". Mirrors the reference wiring in `core/main.core.ts`.
123
144
  */
124
- declare function createWorkletRuntime(options?: WorkletRuntimeOptions): WorkletRuntime;
125
- //#endregion
126
- export { type LoopbackPush, type LoopbackRouteHandler, type LoopbackServer, WorkletRuntime, WorkletRuntimeConfig, WorkletRuntimeOptions, attachWebSocketProtocol, collectRequestBody, createLoopbackPush, createLoopbackServer, createWorkletRuntime, getIPC, resolveCliConfig, resolveWorkletConfig };
145
+ export declare function createWorkletRuntime(options?: WorkletRuntimeOptions): WorkletRuntime;
146
+ export { type LoopbackPush, type LoopbackRouteHandler, type LoopbackServer, collectRequestBody, createLoopbackServer };