@ai-matrx/desktop-protocol 0.1.1 → 0.3.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/dist/react.d.cts CHANGED
@@ -225,10 +225,8 @@ declare const OPS: {
225
225
  }>;
226
226
  size: z.ZodInt;
227
227
  mtime: z.ZodNumber;
228
- mtime_ms: z.ZodInt;
229
228
  mode: z.ZodInt;
230
229
  target: z.ZodNullable<z.ZodString>;
231
- hidden: z.ZodBoolean;
232
230
  }, z.core.$strict>>;
233
231
  truncated: z.ZodBoolean;
234
232
  next_page_token: z.ZodNullable<z.ZodString>;
@@ -252,10 +250,8 @@ declare const OPS: {
252
250
  }>;
253
251
  size: z.ZodInt;
254
252
  mtime: z.ZodNumber;
255
- mtime_ms: z.ZodInt;
256
253
  mode: z.ZodInt;
257
254
  target: z.ZodNullable<z.ZodString>;
258
- hidden: z.ZodBoolean;
259
255
  }, z.core.$strict>;
260
256
  readonly kind: "unary";
261
257
  readonly since: "1.0";
@@ -412,7 +408,6 @@ declare const OPS: {
412
408
  }, z.core.$strict>;
413
409
  readonly result: z.ZodObject<{
414
410
  paths: z.ZodArray<z.ZodString>;
415
- truncated: z.ZodBoolean;
416
411
  }, z.core.$strict>;
417
412
  readonly kind: "unary";
418
413
  readonly since: "1.0";
@@ -434,12 +429,13 @@ declare const OPS: {
434
429
  lines: z.ZodString;
435
430
  line_number: z.ZodInt;
436
431
  submatches: z.ZodArray<z.ZodObject<{
437
- match: z.ZodString;
432
+ match: z.ZodObject<{
433
+ text: z.ZodString;
434
+ }, z.core.$strict>;
438
435
  start: z.ZodInt;
439
436
  end: z.ZodInt;
440
437
  }, z.core.$strict>>;
441
438
  }, z.core.$strict>>;
442
- truncated: z.ZodBoolean;
443
439
  }, z.core.$strict>;
444
440
  readonly kind: "unary";
445
441
  readonly since: "1.0";
@@ -889,6 +885,18 @@ interface DesktopClient {
889
885
  on<E extends EventName>(name: E, handler: EventHandler<E>): () => void;
890
886
  /** Hand the relay a fresh token without dropping the socket. */
891
887
  reauth(token: string): void;
888
+ /**
889
+ * The app came back to the foreground or the network changed (`visibilitychange` → visible,
890
+ * `pageshow`, `online`). Reconnecting → dial now instead of waiting out the backoff. Open → probe:
891
+ * a ping must be answered within `probeMs` (default 4000) or the socket is treated as dead and
892
+ * redialed at once. A phone resumed from sleep often holds a socket the OS already killed, and two
893
+ * silent heartbeats would cost 50 s. Resource streams reattach with `since_seq` as usual.
894
+ */
895
+ wake(options?: WakeOptions): void;
896
+ }
897
+ interface WakeOptions {
898
+ /** How long an open socket has to answer the probe ping. Default 4000. */
899
+ probeMs?: number;
892
900
  }
893
901
 
894
902
  declare function DesktopClientProvider(props: {
@@ -920,5 +928,12 @@ declare function useDesktopRequest<N extends OpName>(op: N, params: OpParams<N>,
920
928
  declare function useDesktopEvent<E extends EventName>(name: E, handler: EventHandler<E>, options?: {
921
929
  client?: DesktopClient;
922
930
  }): void;
931
+ /**
932
+ * Reconnect the moment the person is back: page visible again, a bfcache restore, the network
933
+ * returning, window focus. Each calls `client.wake()` — dial now if reconnecting, probe if open.
934
+ */
935
+ declare function useDesktopWake(client?: DesktopClient, options?: {
936
+ probeMs?: number;
937
+ }): void;
923
938
 
924
- export { DesktopClientProvider, type DesktopRequestState, type UseDesktopRequestOptions, useDesktopClient, useDesktopConnection, useDesktopEvent, useDesktopRequest };
939
+ export { DesktopClientProvider, type DesktopRequestState, type UseDesktopRequestOptions, useDesktopClient, useDesktopConnection, useDesktopEvent, useDesktopRequest, useDesktopWake };
package/dist/react.d.ts CHANGED
@@ -225,10 +225,8 @@ declare const OPS: {
225
225
  }>;
226
226
  size: z.ZodInt;
227
227
  mtime: z.ZodNumber;
228
- mtime_ms: z.ZodInt;
229
228
  mode: z.ZodInt;
230
229
  target: z.ZodNullable<z.ZodString>;
231
- hidden: z.ZodBoolean;
232
230
  }, z.core.$strict>>;
233
231
  truncated: z.ZodBoolean;
234
232
  next_page_token: z.ZodNullable<z.ZodString>;
@@ -252,10 +250,8 @@ declare const OPS: {
252
250
  }>;
253
251
  size: z.ZodInt;
254
252
  mtime: z.ZodNumber;
255
- mtime_ms: z.ZodInt;
256
253
  mode: z.ZodInt;
257
254
  target: z.ZodNullable<z.ZodString>;
258
- hidden: z.ZodBoolean;
259
255
  }, z.core.$strict>;
260
256
  readonly kind: "unary";
261
257
  readonly since: "1.0";
@@ -412,7 +408,6 @@ declare const OPS: {
412
408
  }, z.core.$strict>;
413
409
  readonly result: z.ZodObject<{
414
410
  paths: z.ZodArray<z.ZodString>;
415
- truncated: z.ZodBoolean;
416
411
  }, z.core.$strict>;
417
412
  readonly kind: "unary";
418
413
  readonly since: "1.0";
@@ -434,12 +429,13 @@ declare const OPS: {
434
429
  lines: z.ZodString;
435
430
  line_number: z.ZodInt;
436
431
  submatches: z.ZodArray<z.ZodObject<{
437
- match: z.ZodString;
432
+ match: z.ZodObject<{
433
+ text: z.ZodString;
434
+ }, z.core.$strict>;
438
435
  start: z.ZodInt;
439
436
  end: z.ZodInt;
440
437
  }, z.core.$strict>>;
441
438
  }, z.core.$strict>>;
442
- truncated: z.ZodBoolean;
443
439
  }, z.core.$strict>;
444
440
  readonly kind: "unary";
445
441
  readonly since: "1.0";
@@ -889,6 +885,18 @@ interface DesktopClient {
889
885
  on<E extends EventName>(name: E, handler: EventHandler<E>): () => void;
890
886
  /** Hand the relay a fresh token without dropping the socket. */
891
887
  reauth(token: string): void;
888
+ /**
889
+ * The app came back to the foreground or the network changed (`visibilitychange` → visible,
890
+ * `pageshow`, `online`). Reconnecting → dial now instead of waiting out the backoff. Open → probe:
891
+ * a ping must be answered within `probeMs` (default 4000) or the socket is treated as dead and
892
+ * redialed at once. A phone resumed from sleep often holds a socket the OS already killed, and two
893
+ * silent heartbeats would cost 50 s. Resource streams reattach with `since_seq` as usual.
894
+ */
895
+ wake(options?: WakeOptions): void;
896
+ }
897
+ interface WakeOptions {
898
+ /** How long an open socket has to answer the probe ping. Default 4000. */
899
+ probeMs?: number;
892
900
  }
893
901
 
894
902
  declare function DesktopClientProvider(props: {
@@ -920,5 +928,12 @@ declare function useDesktopRequest<N extends OpName>(op: N, params: OpParams<N>,
920
928
  declare function useDesktopEvent<E extends EventName>(name: E, handler: EventHandler<E>, options?: {
921
929
  client?: DesktopClient;
922
930
  }): void;
931
+ /**
932
+ * Reconnect the moment the person is back: page visible again, a bfcache restore, the network
933
+ * returning, window focus. Each calls `client.wake()` — dial now if reconnecting, probe if open.
934
+ */
935
+ declare function useDesktopWake(client?: DesktopClient, options?: {
936
+ probeMs?: number;
937
+ }): void;
923
938
 
924
- export { DesktopClientProvider, type DesktopRequestState, type UseDesktopRequestOptions, useDesktopClient, useDesktopConnection, useDesktopEvent, useDesktopRequest };
939
+ export { DesktopClientProvider, type DesktopRequestState, type UseDesktopRequestOptions, useDesktopClient, useDesktopConnection, useDesktopEvent, useDesktopRequest, useDesktopWake };
package/dist/react.js CHANGED
@@ -3,6 +3,27 @@
3
3
  // src/react.ts
4
4
  import { createContext, createElement, useCallback, useContext, useEffect, useRef, useState, useSyncExternalStore } from "react";
5
5
 
6
+ // src/client/wake.ts
7
+ function bindDesktopWake(client, options = {}) {
8
+ const targets = options.targets ?? (typeof window !== "undefined" && typeof document !== "undefined" ? { window, document } : null);
9
+ if (!targets) return () => void 0;
10
+ const wakeOptions = options.probeMs === void 0 ? {} : { probeMs: options.probeMs };
11
+ const onVisibility = () => {
12
+ if (targets.document.visibilityState === "visible") client.wake(wakeOptions);
13
+ };
14
+ const onWake = () => client.wake(wakeOptions);
15
+ targets.document.addEventListener("visibilitychange", onVisibility);
16
+ targets.window.addEventListener("pageshow", onWake);
17
+ targets.window.addEventListener("online", onWake);
18
+ targets.window.addEventListener("focus", onWake);
19
+ return () => {
20
+ targets.document.removeEventListener("visibilitychange", onVisibility);
21
+ targets.window.removeEventListener("pageshow", onWake);
22
+ targets.window.removeEventListener("online", onWake);
23
+ targets.window.removeEventListener("focus", onWake);
24
+ };
25
+ }
26
+
6
27
  // src/error.ts
7
28
  var DesktopProtocolError = class extends Error {
8
29
  code;
@@ -99,11 +120,17 @@ function useDesktopEvent(name, handler, options = {}) {
99
120
  handlerRef.current = handler;
100
121
  useEffect(() => c.on(name, ((payload, resourceId) => handlerRef.current(payload, resourceId))), [c, name]);
101
122
  }
123
+ function useDesktopWake(client, options = {}) {
124
+ const c = useDesktopClient(client);
125
+ const probeMs = options.probeMs;
126
+ useEffect(() => bindDesktopWake(c, probeMs === void 0 ? {} : { probeMs }), [c, probeMs]);
127
+ }
102
128
  export {
103
129
  DesktopClientProvider,
104
130
  useDesktopClient,
105
131
  useDesktopConnection,
106
132
  useDesktopEvent,
107
- useDesktopRequest
133
+ useDesktopRequest,
134
+ useDesktopWake
108
135
  };
109
136
  //# sourceMappingURL=react.js.map
package/dist/react.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/react.ts","../src/error.ts"],"sourcesContent":["/**\n * `@ai-matrx/desktop-protocol/react` — hooks over the client: provider, connection state, typed\n * one-shot requests, events. The client owns every hard part (reconnect, reattach, credits); these\n * hooks only bind it to React's lifecycle.\n */\nimport { createContext, createElement, useCallback, useContext, useEffect, useRef, useState, useSyncExternalStore } from \"react\";\nimport type { Context, ReactNode } from \"react\";\nimport type { DesktopClient, DesktopClientState, EventHandler, EventName, RequestOptions } from \"./client/types\";\nimport { DesktopProtocolError } from \"./error\";\nimport type { OpName, OpParams, OpResult } from \"./schema/registry\";\n\n// The context lives on globalThis: an ESM and a CJS copy of this entry in one app (Next.js\n// does this) would otherwise create two contexts and a provider the hooks cannot see.\nconst CONTEXT_SLOT = Symbol.for(\"ai-matrx.desktop-protocol.client-context\");\nfunction clientContext(): Context<DesktopClient | null> {\n const slot = globalThis as { [CONTEXT_SLOT]?: Context<DesktopClient | null> };\n return (slot[CONTEXT_SLOT] ??= createContext<DesktopClient | null>(null));\n}\n\nexport function DesktopClientProvider(props: { client: DesktopClient; children?: ReactNode }): ReactNode {\n return createElement(clientContext().Provider, { value: props.client }, props.children);\n}\n\n/** The client from the nearest provider (or the one passed in). Throws when there is neither. */\nexport function useDesktopClient(client?: DesktopClient): DesktopClient {\n const fromContext = useContext(clientContext());\n const resolved = client ?? fromContext;\n if (!resolved) throw new Error(\"useDesktopClient: wrap the tree in <DesktopClientProvider client={…}> or pass a client\");\n return resolved;\n}\n\n/** Live connection state (status, welcome, attempts, retryInMs, lastError). Connects on mount when idle. */\nexport function useDesktopConnection(client?: DesktopClient): DesktopClientState {\n const c = useDesktopClient(client);\n const state = useSyncExternalStore(c.subscribe, c.getState, c.getState);\n useEffect(() => {\n if (c.getState().status === \"idle\") c.connect();\n }, [c]);\n return state;\n}\n\nexport interface DesktopRequestState<N extends OpName> {\n data: OpResult<N> | undefined;\n error: DesktopProtocolError | undefined;\n loading: boolean;\n /** Re-run now; resolves with the fresh result. */\n refetch: () => Promise<OpResult<N> | undefined>;\n}\n\nexport interface UseDesktopRequestOptions extends Omit<RequestOptions, \"signal\"> {\n /** Default true. False = do not run until refetch() or enabled flips true. */\n enabled?: boolean;\n client?: DesktopClient;\n}\n\n/**\n * Run a unary op and keep its latest result. Re-runs when `op` or the params' JSON changes, and\n * after a reconnect if the last attempt failed with a retryable error. Aborts on unmount.\n */\nexport function useDesktopRequest<N extends OpName>(op: N, params: OpParams<N>, options: UseDesktopRequestOptions = {}): DesktopRequestState<N> {\n const c = useDesktopClient(options.client);\n const enabled = options.enabled ?? true;\n const key = JSON.stringify(params);\n const [data, setData] = useState<OpResult<N> | undefined>(undefined);\n const [error, setError] = useState<DesktopProtocolError | undefined>(undefined);\n const [loading, setLoading] = useState<boolean>(enabled);\n const paramsRef = useRef(params);\n paramsRef.current = params;\n const runRef = useRef(0);\n const abortRef = useRef<AbortController | null>(null);\n const timeoutMs = options.timeoutMs;\n\n const run = useCallback(async (): Promise<OpResult<N> | undefined> => {\n const runId = ++runRef.current;\n abortRef.current?.abort();\n const abort = new AbortController();\n abortRef.current = abort;\n setLoading(true);\n try {\n const result = await c.request(op, paramsRef.current, timeoutMs === undefined ? { signal: abort.signal } : { signal: abort.signal, timeoutMs });\n if (runId === runRef.current) {\n setData(result);\n setError(undefined);\n }\n return result;\n } catch (caught) {\n const err = caught instanceof DesktopProtocolError ? caught : new DesktopProtocolError(\"INTERNAL\", String(caught), { cause: caught });\n if (runId === runRef.current && err.code !== \"CANCELLED\") setError(err);\n return undefined;\n } finally {\n if (runId === runRef.current) setLoading(false);\n }\n // `key` stands for the params' content: a new object with equal JSON is not a new request.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [c, op, key, timeoutMs]);\n\n useEffect(() => {\n if (!enabled) {\n setLoading(false);\n return;\n }\n void run();\n return () => {\n abortRef.current?.abort();\n };\n }, [enabled, run]);\n\n // A retryable failure (device offline, connection lost) re-runs once the client is open again.\n const status = useSyncExternalStore(c.subscribe, () => c.getState().status, () => c.getState().status);\n useEffect(() => {\n if (enabled && status === \"open\" && error?.retryable) void run();\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [status]);\n\n return { data, error, loading, refetch: run };\n}\n\n/** Subscribe to one protocol event (fs.changed, exec.exited, relay.device_status, …) for the component's life. */\nexport function useDesktopEvent<E extends EventName>(name: E, handler: EventHandler<E>, options: { client?: DesktopClient } = {}): void {\n const c = useDesktopClient(options.client);\n const handlerRef = useRef(handler);\n handlerRef.current = handler;\n useEffect(() => c.on(name, ((payload, resourceId) => handlerRef.current(payload, resourceId)) as EventHandler<E>), [c, name]);\n}\n","/**\n * The one error type every package entry throws. It carries the wire ErrorCode (SPEC §5), so a\n * caller branches on `code`/`retryable`/`data.reason` and never parses a message. Zod-free on\n * purpose: `./frame` (the relay hot path) throws it without pulling the schema graph.\n */\nimport type { ErrorCodeName, ErrorData } from \"./types\";\n\nexport class DesktopProtocolError extends Error {\n readonly code: ErrorCodeName;\n readonly retryable: boolean;\n readonly data: ErrorData | undefined;\n\n constructor(code: ErrorCodeName, message: string, options: { retryable?: boolean; data?: ErrorData; cause?: unknown } = {}) {\n super(message, options.cause === undefined ? undefined : { cause: options.cause });\n this.name = \"DesktopProtocolError\";\n this.code = code;\n this.retryable = options.retryable ?? false;\n this.data = options.data;\n }\n\n /** The wire body (ProtocolErrorBody) — what a core or relay sends for this error. */\n toBody(): { code: ErrorCodeName; message: string; retryable: boolean; data?: ErrorData } {\n return this.data === undefined\n ? { code: this.code, message: this.message, retryable: this.retryable }\n : { code: this.code, message: this.message, retryable: this.retryable, data: this.data };\n }\n}\n\nexport function isDesktopProtocolError(value: unknown): value is DesktopProtocolError {\n return value instanceof DesktopProtocolError || (value instanceof Error && value.name === \"DesktopProtocolError\" && \"code\" in value);\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../src/react.ts","../src/client/wake.ts","../src/error.ts"],"sourcesContent":["/**\n * `@ai-matrx/desktop-protocol/react` — hooks over the client: provider, connection state, typed\n * one-shot requests, events. The client owns every hard part (reconnect, reattach, credits); these\n * hooks only bind it to React's lifecycle.\n */\nimport { createContext, createElement, useCallback, useContext, useEffect, useRef, useState, useSyncExternalStore } from \"react\";\nimport type { Context, ReactNode } from \"react\";\nimport type { DesktopClient, DesktopClientState, EventHandler, EventName, RequestOptions } from \"./client/types\";\nimport { bindDesktopWake } from \"./client/wake\";\nimport { DesktopProtocolError } from \"./error\";\nimport type { OpName, OpParams, OpResult } from \"./schema/registry\";\n\n// The context lives on globalThis: an ESM and a CJS copy of this entry in one app (Next.js\n// does this) would otherwise create two contexts and a provider the hooks cannot see.\nconst CONTEXT_SLOT = Symbol.for(\"ai-matrx.desktop-protocol.client-context\");\nfunction clientContext(): Context<DesktopClient | null> {\n const slot = globalThis as { [CONTEXT_SLOT]?: Context<DesktopClient | null> };\n return (slot[CONTEXT_SLOT] ??= createContext<DesktopClient | null>(null));\n}\n\nexport function DesktopClientProvider(props: { client: DesktopClient; children?: ReactNode }): ReactNode {\n return createElement(clientContext().Provider, { value: props.client }, props.children);\n}\n\n/** The client from the nearest provider (or the one passed in). Throws when there is neither. */\nexport function useDesktopClient(client?: DesktopClient): DesktopClient {\n const fromContext = useContext(clientContext());\n const resolved = client ?? fromContext;\n if (!resolved) throw new Error(\"useDesktopClient: wrap the tree in <DesktopClientProvider client={…}> or pass a client\");\n return resolved;\n}\n\n/** Live connection state (status, welcome, attempts, retryInMs, lastError). Connects on mount when idle. */\nexport function useDesktopConnection(client?: DesktopClient): DesktopClientState {\n const c = useDesktopClient(client);\n const state = useSyncExternalStore(c.subscribe, c.getState, c.getState);\n useEffect(() => {\n if (c.getState().status === \"idle\") c.connect();\n }, [c]);\n return state;\n}\n\nexport interface DesktopRequestState<N extends OpName> {\n data: OpResult<N> | undefined;\n error: DesktopProtocolError | undefined;\n loading: boolean;\n /** Re-run now; resolves with the fresh result. */\n refetch: () => Promise<OpResult<N> | undefined>;\n}\n\nexport interface UseDesktopRequestOptions extends Omit<RequestOptions, \"signal\"> {\n /** Default true. False = do not run until refetch() or enabled flips true. */\n enabled?: boolean;\n client?: DesktopClient;\n}\n\n/**\n * Run a unary op and keep its latest result. Re-runs when `op` or the params' JSON changes, and\n * after a reconnect if the last attempt failed with a retryable error. Aborts on unmount.\n */\nexport function useDesktopRequest<N extends OpName>(op: N, params: OpParams<N>, options: UseDesktopRequestOptions = {}): DesktopRequestState<N> {\n const c = useDesktopClient(options.client);\n const enabled = options.enabled ?? true;\n const key = JSON.stringify(params);\n const [data, setData] = useState<OpResult<N> | undefined>(undefined);\n const [error, setError] = useState<DesktopProtocolError | undefined>(undefined);\n const [loading, setLoading] = useState<boolean>(enabled);\n const paramsRef = useRef(params);\n paramsRef.current = params;\n const runRef = useRef(0);\n const abortRef = useRef<AbortController | null>(null);\n const timeoutMs = options.timeoutMs;\n\n const run = useCallback(async (): Promise<OpResult<N> | undefined> => {\n const runId = ++runRef.current;\n abortRef.current?.abort();\n const abort = new AbortController();\n abortRef.current = abort;\n setLoading(true);\n try {\n const result = await c.request(op, paramsRef.current, timeoutMs === undefined ? { signal: abort.signal } : { signal: abort.signal, timeoutMs });\n if (runId === runRef.current) {\n setData(result);\n setError(undefined);\n }\n return result;\n } catch (caught) {\n const err = caught instanceof DesktopProtocolError ? caught : new DesktopProtocolError(\"INTERNAL\", String(caught), { cause: caught });\n if (runId === runRef.current && err.code !== \"CANCELLED\") setError(err);\n return undefined;\n } finally {\n if (runId === runRef.current) setLoading(false);\n }\n // `key` stands for the params' content: a new object with equal JSON is not a new request.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [c, op, key, timeoutMs]);\n\n useEffect(() => {\n if (!enabled) {\n setLoading(false);\n return;\n }\n void run();\n return () => {\n abortRef.current?.abort();\n };\n }, [enabled, run]);\n\n // A retryable failure (device offline, connection lost) re-runs once the client is open again.\n const status = useSyncExternalStore(c.subscribe, () => c.getState().status, () => c.getState().status);\n useEffect(() => {\n if (enabled && status === \"open\" && error?.retryable) void run();\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [status]);\n\n return { data, error, loading, refetch: run };\n}\n\n/** Subscribe to one protocol event (fs.changed, exec.exited, relay.device_status, …) for the component's life. */\nexport function useDesktopEvent<E extends EventName>(name: E, handler: EventHandler<E>, options: { client?: DesktopClient } = {}): void {\n const c = useDesktopClient(options.client);\n const handlerRef = useRef(handler);\n handlerRef.current = handler;\n useEffect(() => c.on(name, ((payload, resourceId) => handlerRef.current(payload, resourceId)) as EventHandler<E>), [c, name]);\n}\n\n/**\n * Reconnect the moment the person is back: page visible again, a bfcache restore, the network\n * returning, window focus. Each calls `client.wake()` — dial now if reconnecting, probe if open.\n */\nexport function useDesktopWake(client?: DesktopClient, options: { probeMs?: number } = {}): void {\n const c = useDesktopClient(client);\n const probeMs = options.probeMs;\n useEffect(() => bindDesktopWake(c, probeMs === undefined ? {} : { probeMs }), [c, probeMs]);\n}\n","/**\n * Wire a client's wake() to the browser events that mean \"the person is back\": the page becomes\n * visible again (iOS Safari suspends a background tab's sockets), a back/forward-cache restore\n * (`pageshow` with persisted), and the network returning (`online`). Framework-free; the React\n * binding is `useDesktopWake` in `./react`.\n */\nimport type { DesktopClient, WakeOptions } from \"./types\";\n\n/** The subset of window/document the binding listens on — injectable for tests and non-DOM hosts. */\nexport interface WakeTargets {\n window: Pick<Window, \"addEventListener\" | \"removeEventListener\">;\n document: Pick<Document, \"addEventListener\" | \"removeEventListener\" | \"visibilityState\">;\n}\n\nexport function bindDesktopWake(client: Pick<DesktopClient, \"wake\">, options: WakeOptions & { targets?: WakeTargets } = {}): () => void {\n const targets: WakeTargets | null =\n options.targets ?? (typeof window !== \"undefined\" && typeof document !== \"undefined\" ? { window, document } : null);\n if (!targets) return () => undefined;\n const wakeOptions: WakeOptions = options.probeMs === undefined ? {} : { probeMs: options.probeMs };\n const onVisibility = () => {\n if (targets.document.visibilityState === \"visible\") client.wake(wakeOptions);\n };\n const onWake = () => client.wake(wakeOptions);\n targets.document.addEventListener(\"visibilitychange\", onVisibility);\n targets.window.addEventListener(\"pageshow\", onWake);\n targets.window.addEventListener(\"online\", onWake);\n targets.window.addEventListener(\"focus\", onWake);\n return () => {\n targets.document.removeEventListener(\"visibilitychange\", onVisibility);\n targets.window.removeEventListener(\"pageshow\", onWake);\n targets.window.removeEventListener(\"online\", onWake);\n targets.window.removeEventListener(\"focus\", onWake);\n };\n}\n","/**\n * The one error type every package entry throws. It carries the wire ErrorCode (SPEC §5), so a\n * caller branches on `code`/`retryable`/`data.reason` and never parses a message. Zod-free on\n * purpose: `./frame` (the relay hot path) throws it without pulling the schema graph.\n */\nimport type { ErrorCodeName, ErrorData } from \"./types\";\n\nexport class DesktopProtocolError extends Error {\n readonly code: ErrorCodeName;\n readonly retryable: boolean;\n readonly data: ErrorData | undefined;\n\n constructor(code: ErrorCodeName, message: string, options: { retryable?: boolean; data?: ErrorData; cause?: unknown } = {}) {\n super(message, options.cause === undefined ? undefined : { cause: options.cause });\n this.name = \"DesktopProtocolError\";\n this.code = code;\n this.retryable = options.retryable ?? false;\n this.data = options.data;\n }\n\n /** The wire body (ProtocolErrorBody) — what a core or relay sends for this error. */\n toBody(): { code: ErrorCodeName; message: string; retryable: boolean; data?: ErrorData } {\n return this.data === undefined\n ? { code: this.code, message: this.message, retryable: this.retryable }\n : { code: this.code, message: this.message, retryable: this.retryable, data: this.data };\n }\n}\n\nexport function isDesktopProtocolError(value: unknown): value is DesktopProtocolError {\n return value instanceof DesktopProtocolError || (value instanceof Error && value.name === \"DesktopProtocolError\" && \"code\" in value);\n}\n"],"mappings":"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","names":[]}
@@ -56,6 +56,12 @@ declare function isDesktopProtocolError(value: unknown): value is DesktopProtoco
56
56
  */
57
57
  declare const PING_TEXT: "{\"type\":\"ping\"}";
58
58
  declare const PONG_TEXT: "{\"type\":\"pong\"}";
59
+ /**
60
+ * Every WebSocket (device, phone, browser, localhost) offers this subprotocol; the access token
61
+ * rides beside it as `${BEARER_PREFIX}<token>`, never in the URL. The server echoes only SUBPROTOCOL.
62
+ */
63
+ declare const SUBPROTOCOL: "matrx.v1";
64
+ declare const BEARER_PREFIX: "bearer.";
59
65
  declare const CloseCode: {
60
66
  readonly NORMAL: 1000;
61
67
  readonly GOING_AWAY: 1001;
@@ -636,10 +642,8 @@ declare const OPS: {
636
642
  }>;
637
643
  size: z.ZodInt;
638
644
  mtime: z.ZodNumber;
639
- mtime_ms: z.ZodInt;
640
645
  mode: z.ZodInt;
641
646
  target: z.ZodNullable<z.ZodString>;
642
- hidden: z.ZodBoolean;
643
647
  }, z.core.$strict>>;
644
648
  truncated: z.ZodBoolean;
645
649
  next_page_token: z.ZodNullable<z.ZodString>;
@@ -663,10 +667,8 @@ declare const OPS: {
663
667
  }>;
664
668
  size: z.ZodInt;
665
669
  mtime: z.ZodNumber;
666
- mtime_ms: z.ZodInt;
667
670
  mode: z.ZodInt;
668
671
  target: z.ZodNullable<z.ZodString>;
669
- hidden: z.ZodBoolean;
670
672
  }, z.core.$strict>;
671
673
  readonly kind: "unary";
672
674
  readonly since: "1.0";
@@ -823,7 +825,6 @@ declare const OPS: {
823
825
  }, z.core.$strict>;
824
826
  readonly result: z.ZodObject<{
825
827
  paths: z.ZodArray<z.ZodString>;
826
- truncated: z.ZodBoolean;
827
828
  }, z.core.$strict>;
828
829
  readonly kind: "unary";
829
830
  readonly since: "1.0";
@@ -845,12 +846,13 @@ declare const OPS: {
845
846
  lines: z.ZodString;
846
847
  line_number: z.ZodInt;
847
848
  submatches: z.ZodArray<z.ZodObject<{
848
- match: z.ZodString;
849
+ match: z.ZodObject<{
850
+ text: z.ZodString;
851
+ }, z.core.$strict>;
849
852
  start: z.ZodInt;
850
853
  end: z.ZodInt;
851
854
  }, z.core.$strict>>;
852
855
  }, z.core.$strict>>;
853
- truncated: z.ZodBoolean;
854
856
  }, z.core.$strict>;
855
857
  readonly kind: "unary";
856
858
  readonly since: "1.0";
@@ -1758,10 +1760,8 @@ declare const NAMED_SCHEMAS: {
1758
1760
  }>;
1759
1761
  size: z.ZodInt;
1760
1762
  mtime: z.ZodNumber;
1761
- mtime_ms: z.ZodInt;
1762
1763
  mode: z.ZodInt;
1763
1764
  target: z.ZodNullable<z.ZodString>;
1764
- hidden: z.ZodBoolean;
1765
1765
  }, z.core.$strict>;
1766
1766
  readonly FsListParams: z.ZodObject<{
1767
1767
  path: z.ZodString;
@@ -1789,10 +1789,8 @@ declare const NAMED_SCHEMAS: {
1789
1789
  }>;
1790
1790
  size: z.ZodInt;
1791
1791
  mtime: z.ZodNumber;
1792
- mtime_ms: z.ZodInt;
1793
1792
  mode: z.ZodInt;
1794
1793
  target: z.ZodNullable<z.ZodString>;
1795
- hidden: z.ZodBoolean;
1796
1794
  }, z.core.$strict>>;
1797
1795
  truncated: z.ZodBoolean;
1798
1796
  next_page_token: z.ZodNullable<z.ZodString>;
@@ -1915,7 +1913,6 @@ declare const NAMED_SCHEMAS: {
1915
1913
  }, z.core.$strict>;
1916
1914
  readonly FsSearchPathsResult: z.ZodObject<{
1917
1915
  paths: z.ZodArray<z.ZodString>;
1918
- truncated: z.ZodBoolean;
1919
1916
  }, z.core.$strict>;
1920
1917
  readonly FsSearchContentParams: z.ZodObject<{
1921
1918
  query: z.ZodString;
@@ -1932,12 +1929,13 @@ declare const NAMED_SCHEMAS: {
1932
1929
  lines: z.ZodString;
1933
1930
  line_number: z.ZodInt;
1934
1931
  submatches: z.ZodArray<z.ZodObject<{
1935
- match: z.ZodString;
1932
+ match: z.ZodObject<{
1933
+ text: z.ZodString;
1934
+ }, z.core.$strict>;
1936
1935
  start: z.ZodInt;
1937
1936
  end: z.ZodInt;
1938
1937
  }, z.core.$strict>>;
1939
1938
  }, z.core.$strict>>;
1940
- truncated: z.ZodBoolean;
1941
1939
  }, z.core.$strict>;
1942
1940
  readonly FsChange: z.ZodObject<{
1943
1941
  type: z.ZodEnum<{
@@ -2368,4 +2366,4 @@ declare const NAMED_SCHEMAS: {
2368
2366
  };
2369
2367
  type NamedSchemaId = keyof typeof NAMED_SCHEMAS;
2370
2368
 
2371
- export { ResponseMsg as A, StreamMsg as B, ClientType as C, DesktopProtocolError as D, EndReason as E, HelloMsg as H, Limits as L, NAMED_SCHEMAS as N, type OpName as O, PING_TEXT as P, RelayMsg as R, StreamMeta as S, Welcome as W, type OpParams as a, type OpResult as b, OPS as c, EVENTS as d, CancelMsg as e, ClientToCoreMsg as f, CloseCode as g, CloseCodeValue as h, isDesktopProtocolError as i, CoreToClientMsg as j, CreditMsg as k, EndMsg as l, ErrorCode as m, type ErrorCodeName as n, type ErrorData as o, ErrorMsg as p, ErrorReason as q, type ErrorReasonName as r, EventMsg as s, type EventName as t, type NamedSchemaId as u, OpDescriptor as v, type OpSpec as w, PONG_TEXT as x, ProtocolErrorBody as y, RequestMsg as z };
2369
+ export { ResponseMsg as A, BEARER_PREFIX as B, ClientType as C, DesktopProtocolError as D, EndReason as E, SUBPROTOCOL as F, StreamMsg as G, HelloMsg as H, Limits as L, NAMED_SCHEMAS as N, type OpName as O, PING_TEXT as P, RelayMsg as R, StreamMeta as S, Welcome as W, type OpParams as a, type OpResult as b, OPS as c, EVENTS as d, CancelMsg as e, ClientToCoreMsg as f, CloseCode as g, CloseCodeValue as h, isDesktopProtocolError as i, CoreToClientMsg as j, CreditMsg as k, EndMsg as l, ErrorCode as m, type ErrorCodeName as n, type ErrorData as o, ErrorMsg as p, ErrorReason as q, type ErrorReasonName as r, EventMsg as s, type EventName as t, type NamedSchemaId as u, OpDescriptor as v, type OpSpec as w, PONG_TEXT as x, ProtocolErrorBody as y, RequestMsg as z };
@@ -56,6 +56,12 @@ declare function isDesktopProtocolError(value: unknown): value is DesktopProtoco
56
56
  */
57
57
  declare const PING_TEXT: "{\"type\":\"ping\"}";
58
58
  declare const PONG_TEXT: "{\"type\":\"pong\"}";
59
+ /**
60
+ * Every WebSocket (device, phone, browser, localhost) offers this subprotocol; the access token
61
+ * rides beside it as `${BEARER_PREFIX}<token>`, never in the URL. The server echoes only SUBPROTOCOL.
62
+ */
63
+ declare const SUBPROTOCOL: "matrx.v1";
64
+ declare const BEARER_PREFIX: "bearer.";
59
65
  declare const CloseCode: {
60
66
  readonly NORMAL: 1000;
61
67
  readonly GOING_AWAY: 1001;
@@ -636,10 +642,8 @@ declare const OPS: {
636
642
  }>;
637
643
  size: z.ZodInt;
638
644
  mtime: z.ZodNumber;
639
- mtime_ms: z.ZodInt;
640
645
  mode: z.ZodInt;
641
646
  target: z.ZodNullable<z.ZodString>;
642
- hidden: z.ZodBoolean;
643
647
  }, z.core.$strict>>;
644
648
  truncated: z.ZodBoolean;
645
649
  next_page_token: z.ZodNullable<z.ZodString>;
@@ -663,10 +667,8 @@ declare const OPS: {
663
667
  }>;
664
668
  size: z.ZodInt;
665
669
  mtime: z.ZodNumber;
666
- mtime_ms: z.ZodInt;
667
670
  mode: z.ZodInt;
668
671
  target: z.ZodNullable<z.ZodString>;
669
- hidden: z.ZodBoolean;
670
672
  }, z.core.$strict>;
671
673
  readonly kind: "unary";
672
674
  readonly since: "1.0";
@@ -823,7 +825,6 @@ declare const OPS: {
823
825
  }, z.core.$strict>;
824
826
  readonly result: z.ZodObject<{
825
827
  paths: z.ZodArray<z.ZodString>;
826
- truncated: z.ZodBoolean;
827
828
  }, z.core.$strict>;
828
829
  readonly kind: "unary";
829
830
  readonly since: "1.0";
@@ -845,12 +846,13 @@ declare const OPS: {
845
846
  lines: z.ZodString;
846
847
  line_number: z.ZodInt;
847
848
  submatches: z.ZodArray<z.ZodObject<{
848
- match: z.ZodString;
849
+ match: z.ZodObject<{
850
+ text: z.ZodString;
851
+ }, z.core.$strict>;
849
852
  start: z.ZodInt;
850
853
  end: z.ZodInt;
851
854
  }, z.core.$strict>>;
852
855
  }, z.core.$strict>>;
853
- truncated: z.ZodBoolean;
854
856
  }, z.core.$strict>;
855
857
  readonly kind: "unary";
856
858
  readonly since: "1.0";
@@ -1758,10 +1760,8 @@ declare const NAMED_SCHEMAS: {
1758
1760
  }>;
1759
1761
  size: z.ZodInt;
1760
1762
  mtime: z.ZodNumber;
1761
- mtime_ms: z.ZodInt;
1762
1763
  mode: z.ZodInt;
1763
1764
  target: z.ZodNullable<z.ZodString>;
1764
- hidden: z.ZodBoolean;
1765
1765
  }, z.core.$strict>;
1766
1766
  readonly FsListParams: z.ZodObject<{
1767
1767
  path: z.ZodString;
@@ -1789,10 +1789,8 @@ declare const NAMED_SCHEMAS: {
1789
1789
  }>;
1790
1790
  size: z.ZodInt;
1791
1791
  mtime: z.ZodNumber;
1792
- mtime_ms: z.ZodInt;
1793
1792
  mode: z.ZodInt;
1794
1793
  target: z.ZodNullable<z.ZodString>;
1795
- hidden: z.ZodBoolean;
1796
1794
  }, z.core.$strict>>;
1797
1795
  truncated: z.ZodBoolean;
1798
1796
  next_page_token: z.ZodNullable<z.ZodString>;
@@ -1915,7 +1913,6 @@ declare const NAMED_SCHEMAS: {
1915
1913
  }, z.core.$strict>;
1916
1914
  readonly FsSearchPathsResult: z.ZodObject<{
1917
1915
  paths: z.ZodArray<z.ZodString>;
1918
- truncated: z.ZodBoolean;
1919
1916
  }, z.core.$strict>;
1920
1917
  readonly FsSearchContentParams: z.ZodObject<{
1921
1918
  query: z.ZodString;
@@ -1932,12 +1929,13 @@ declare const NAMED_SCHEMAS: {
1932
1929
  lines: z.ZodString;
1933
1930
  line_number: z.ZodInt;
1934
1931
  submatches: z.ZodArray<z.ZodObject<{
1935
- match: z.ZodString;
1932
+ match: z.ZodObject<{
1933
+ text: z.ZodString;
1934
+ }, z.core.$strict>;
1936
1935
  start: z.ZodInt;
1937
1936
  end: z.ZodInt;
1938
1937
  }, z.core.$strict>>;
1939
1938
  }, z.core.$strict>>;
1940
- truncated: z.ZodBoolean;
1941
1939
  }, z.core.$strict>;
1942
1940
  readonly FsChange: z.ZodObject<{
1943
1941
  type: z.ZodEnum<{
@@ -2368,4 +2366,4 @@ declare const NAMED_SCHEMAS: {
2368
2366
  };
2369
2367
  type NamedSchemaId = keyof typeof NAMED_SCHEMAS;
2370
2368
 
2371
- export { ResponseMsg as A, StreamMsg as B, ClientType as C, DesktopProtocolError as D, EndReason as E, HelloMsg as H, Limits as L, NAMED_SCHEMAS as N, type OpName as O, PING_TEXT as P, RelayMsg as R, StreamMeta as S, Welcome as W, type OpParams as a, type OpResult as b, OPS as c, EVENTS as d, CancelMsg as e, ClientToCoreMsg as f, CloseCode as g, CloseCodeValue as h, isDesktopProtocolError as i, CoreToClientMsg as j, CreditMsg as k, EndMsg as l, ErrorCode as m, type ErrorCodeName as n, type ErrorData as o, ErrorMsg as p, ErrorReason as q, type ErrorReasonName as r, EventMsg as s, type EventName as t, type NamedSchemaId as u, OpDescriptor as v, type OpSpec as w, PONG_TEXT as x, ProtocolErrorBody as y, RequestMsg as z };
2369
+ export { ResponseMsg as A, BEARER_PREFIX as B, ClientType as C, DesktopProtocolError as D, EndReason as E, SUBPROTOCOL as F, StreamMsg as G, HelloMsg as H, Limits as L, NAMED_SCHEMAS as N, type OpName as O, PING_TEXT as P, RelayMsg as R, StreamMeta as S, Welcome as W, type OpParams as a, type OpResult as b, OPS as c, EVENTS as d, CancelMsg as e, ClientToCoreMsg as f, CloseCode as g, CloseCodeValue as h, isDesktopProtocolError as i, CoreToClientMsg as j, CreditMsg as k, EndMsg as l, ErrorCode as m, type ErrorCodeName as n, type ErrorData as o, ErrorMsg as p, ErrorReason as q, type ErrorReasonName as r, EventMsg as s, type EventName as t, type NamedSchemaId as u, OpDescriptor as v, type OpSpec as w, PONG_TEXT as x, ProtocolErrorBody as y, RequestMsg as z };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ai-matrx/desktop-protocol",
3
- "version": "0.1.1",
3
+ "version": "0.3.0",
4
4
  "description": "The one wire contract between Matrx 2 (the desktop app) and every client that drives it — phone, web app, extension, server: zod schemas for the envelope and every cap.op, the 16-byte binary frame codec, a reconnecting request/stream/credit/reattach client, React hooks, and a generated JSON Schema + Pydantic twin that CI keeps byte-identical.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",