syncorejs 0.2.3 → 0.2.5
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/_dashboard/assets/ConfirmActionDialog-Db4VzVp6.js +1 -0
- package/dist/_dashboard/assets/circle-x-VsB4Z8W4.js +1 -0
- package/dist/_dashboard/assets/data.lazy-DjdU9CzX.js +18 -0
- package/dist/_dashboard/assets/file-code-BrOKjG4n.js +1 -0
- package/dist/_dashboard/assets/functions.lazy-DvDwAGHq.js +1 -0
- package/dist/_dashboard/assets/funnel-BH8EMMJI.js +1 -0
- package/dist/_dashboard/assets/index-DT9ZEELb.css +1 -0
- package/dist/_dashboard/assets/index-DrSG4qZZ.js +54 -0
- package/dist/_dashboard/assets/loader-circle-CmJFSYga.js +1 -0
- package/dist/_dashboard/assets/logs.lazy-50KTk5yd.js +1 -0
- package/dist/_dashboard/assets/play-DS52VsLN.js +1 -0
- package/dist/_dashboard/assets/queries.lazy-CfysRWkz.js +1 -0
- package/dist/_dashboard/assets/scheduler.lazy-BB88mZk-.js +1 -0
- package/dist/_dashboard/assets/select-THYcR8Wt.js +1 -0
- package/dist/_dashboard/assets/separator-BU7xg615.js +1 -0
- package/dist/_dashboard/assets/shared-Bh0wwC2k.js +1 -0
- package/dist/_dashboard/assets/sql.lazy-CHtU9Qnt.js +13 -0
- package/dist/_dashboard/assets/storage.lazy-CneN7wVU.js +1 -0
- package/dist/_dashboard/assets/table-2-CH8JoMXf.js +1 -0
- package/dist/_dashboard/index.html +18 -0
- package/dist/_vendor/cli/app.d.mts.map +1 -1
- package/dist/_vendor/cli/app.mjs +16 -5
- package/dist/_vendor/cli/app.mjs.map +1 -1
- package/dist/_vendor/core/cli.d.mts.map +1 -1
- package/dist/_vendor/core/cli.mjs +358 -16
- package/dist/_vendor/core/cli.mjs.map +1 -1
- package/dist/_vendor/core/index.d.mts +3 -3
- package/dist/_vendor/core/runtime/devtools.d.mts.map +1 -1
- package/dist/_vendor/core/runtime/devtools.mjs +131 -0
- package/dist/_vendor/core/runtime/devtools.mjs.map +1 -1
- package/dist/_vendor/core/runtime/functions.d.mts +3 -3
- package/dist/_vendor/core/runtime/functions.mjs.map +1 -1
- package/dist/_vendor/core/runtime/internal/engines/devtoolsEngine.mjs +1 -1
- package/dist/_vendor/core/runtime/internal/engines/devtoolsEngine.mjs.map +1 -1
- package/dist/_vendor/core/runtime/internal/engines/executionEngine.mjs +4 -1
- package/dist/_vendor/core/runtime/internal/engines/executionEngine.mjs.map +1 -1
- package/dist/_vendor/core/runtime/internal/engines/reactivityEngine.mjs +6 -3
- package/dist/_vendor/core/runtime/internal/engines/reactivityEngine.mjs.map +1 -1
- package/dist/_vendor/core/runtime/internal/engines/shared.mjs +5 -1
- package/dist/_vendor/core/runtime/internal/engines/shared.mjs.map +1 -1
- package/dist/_vendor/core/runtime/internal/engines/storageEngine.mjs +99 -13
- package/dist/_vendor/core/runtime/internal/engines/storageEngine.mjs.map +1 -1
- package/dist/_vendor/core/runtime/internal/runtimeKernel.mjs +38 -4
- package/dist/_vendor/core/runtime/internal/runtimeKernel.mjs.map +1 -1
- package/dist/_vendor/core/runtime/runtime.d.mts +65 -8
- package/dist/_vendor/core/runtime/runtime.d.mts.map +1 -1
- package/dist/_vendor/core/runtime/runtime.mjs.map +1 -1
- package/dist/_vendor/core/transport.d.mts.map +1 -1
- package/dist/_vendor/core/transport.mjs +30 -5
- package/dist/_vendor/core/transport.mjs.map +1 -1
- package/dist/_vendor/devtools-protocol/index.d.ts +75 -1
- package/dist/_vendor/devtools-protocol/index.d.ts.map +1 -1
- package/dist/_vendor/devtools-protocol/index.js.map +1 -1
- package/dist/_vendor/next/index.js +9 -1
- package/dist/_vendor/next/index.js.map +1 -1
- package/dist/_vendor/platform-expo/index.d.ts +1 -1
- package/dist/_vendor/platform-expo/index.d.ts.map +1 -1
- package/dist/_vendor/platform-expo/index.js +6 -1
- package/dist/_vendor/platform-expo/index.js.map +1 -1
- package/dist/_vendor/platform-node/index.d.mts +2 -1
- package/dist/_vendor/platform-node/index.d.mts.map +1 -1
- package/dist/_vendor/platform-node/index.mjs +27 -2
- package/dist/_vendor/platform-node/index.mjs.map +1 -1
- package/dist/_vendor/platform-node/ipc-react.mjs +4 -0
- package/dist/_vendor/platform-node/ipc-react.mjs.map +1 -1
- package/dist/_vendor/platform-web/external-change.d.ts +2 -2
- package/dist/_vendor/platform-web/external-change.js +2 -2
- package/dist/_vendor/platform-web/external-change.js.map +1 -1
- package/dist/_vendor/platform-web/index.d.ts +13 -10
- package/dist/_vendor/platform-web/index.d.ts.map +1 -1
- package/dist/_vendor/platform-web/index.js +66 -10
- package/dist/_vendor/platform-web/index.js.map +1 -1
- package/dist/_vendor/platform-web/indexeddb.d.ts +3 -3
- package/dist/_vendor/platform-web/indexeddb.js +3 -3
- package/dist/_vendor/platform-web/indexeddb.js.map +1 -1
- package/dist/_vendor/platform-web/opfs.d.ts +3 -1
- package/dist/_vendor/platform-web/opfs.d.ts.map +1 -1
- package/dist/_vendor/platform-web/opfs.js +29 -3
- package/dist/_vendor/platform-web/opfs.js.map +1 -1
- package/dist/_vendor/platform-web/persistence.d.ts +31 -1
- package/dist/_vendor/platform-web/persistence.d.ts.map +1 -1
- package/dist/_vendor/platform-web/persistence.js.map +1 -1
- package/dist/_vendor/platform-web/react.d.ts.map +1 -1
- package/dist/_vendor/platform-web/react.js +9 -1
- package/dist/_vendor/platform-web/react.js.map +1 -1
- package/dist/_vendor/react/index.d.ts +6 -5
- package/dist/_vendor/react/index.d.ts.map +1 -1
- package/dist/_vendor/react/index.js +6 -5
- package/dist/_vendor/react/index.js.map +1 -1
- package/dist/_vendor/svelte/index.d.ts +8 -6
- package/dist/_vendor/svelte/index.d.ts.map +1 -1
- package/dist/_vendor/svelte/index.js +7 -5
- package/dist/_vendor/svelte/index.js.map +1 -1
- package/package.json +2 -2
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"transport.mjs","names":[],"sources":["../src/transport.ts"],"sourcesContent":["import {\n type SyncoreClient,\n type SyncoreRuntime,\n type JsonObject,\n type SyncoreRuntimeStatus,\n type SyncoreWatch\n} from \"./runtime/runtime.js\";\nimport type { SyncoreSchema } from \"@syncore/schema\";\nimport { generateId } from \"./runtime/id.js\";\nimport type { FunctionReference } from \"./runtime/functions.js\";\nimport { RuntimeStatusController } from \"./runtime/internal/runtimeStatus.js\";\n\nexport interface SyncoreBridgeMessageEndpoint {\n postMessage(message: unknown): void;\n addEventListener(\n type: \"message\",\n listener: (event: MessageEvent<unknown>) => void\n ): void;\n removeEventListener(\n type: \"message\",\n listener: (event: MessageEvent<unknown>) => void\n ): void;\n}\n\nexport type SyncoreBridgeRequest =\n | {\n type: \"runtime.status.request\";\n }\n | {\n type: \"invoke\";\n requestId: string;\n kind: \"query\";\n reference: FunctionReference<\"query\", unknown, unknown>;\n args: JsonObject;\n }\n | {\n type: \"invoke\";\n requestId: string;\n kind: \"mutation\";\n reference: FunctionReference<\"mutation\", unknown, unknown>;\n args: JsonObject;\n }\n | {\n type: \"invoke\";\n requestId: string;\n kind: \"action\";\n reference: FunctionReference<\"action\", unknown, unknown>;\n args: JsonObject;\n }\n | {\n type: \"watch.subscribe\";\n subscriptionId: string;\n reference: FunctionReference<\"query\", unknown, unknown>;\n args: JsonObject;\n }\n | {\n type: \"watch.unsubscribe\";\n subscriptionId: string;\n };\n\nexport type SyncoreBridgeResponse =\n | { type: \"runtime.ready\" }\n | { type: \"runtime.error\"; error: string }\n | { type: \"runtime.status\"; status: SyncoreRuntimeStatus }\n | {\n type: \"invoke.result\";\n requestId: string;\n success: true;\n value: unknown;\n }\n | {\n type: \"invoke.result\";\n requestId: string;\n success: false;\n error: string;\n }\n | {\n type: \"watch.update\";\n subscriptionId: string;\n success: true;\n value: unknown;\n }\n | {\n type: \"watch.update\";\n subscriptionId: string;\n success: false;\n error: string;\n };\n\ntype PendingRequest = {\n resolve(value: unknown): void;\n reject(error: Error): void;\n};\n\ntype WatchRecord = {\n subscriptionId: string;\n listeners: Set<() => void>;\n consumers: number;\n result: unknown;\n error: Error | undefined;\n};\n\ntype OptionalArgsTuple<TArgs> =\n Record<never, never> extends TArgs ? [args?: TArgs] : [args: TArgs];\n\nexport type BridgeQueryWatch<TValue> = SyncoreWatch<TValue> & {\n dispose(): void;\n};\n\nexport class SyncoreBridgeClient implements SyncoreClient {\n private readonly pendingRequests = new Map<string, PendingRequest>();\n private readonly watchRecordsByKey = new Map<string, WatchRecord>();\n private readonly watchKeyBySubscriptionId = new Map<string, string>();\n private readonly runtimeStatus = new RuntimeStatusController({\n kind: \"starting\",\n reason: \"booting\"\n });\n private disposed = false;\n\n private readonly handleMessage = (event: MessageEvent<unknown>) => {\n const message = event.data as SyncoreBridgeResponse;\n if (!message || typeof message !== \"object\" || !(\"type\" in message)) {\n return;\n }\n\n switch (message.type) {\n case \"runtime.ready\":\n this.runtimeStatus.setStatus({\n kind: \"ready\"\n });\n return;\n case \"runtime.error\":\n this.runtimeStatus.setStatus({\n kind: \"error\",\n reason: \"runtime-unavailable\",\n error: new Error(message.error)\n });\n for (const watchRecord of this.watchRecordsByKey.values()) {\n for (const listener of watchRecord.listeners) {\n listener();\n }\n }\n this.rejectAllPending(new Error(message.error));\n return;\n case \"runtime.status\":\n this.runtimeStatus.setStatus(message.status);\n for (const watchRecord of this.watchRecordsByKey.values()) {\n for (const listener of watchRecord.listeners) {\n listener();\n }\n }\n if (message.status.error) {\n this.rejectAllPending(message.status.error);\n }\n return;\n case \"invoke.result\": {\n const pending = this.pendingRequests.get(message.requestId);\n if (!pending) {\n return;\n }\n this.pendingRequests.delete(message.requestId);\n if (message.success) {\n pending.resolve(message.value);\n } else {\n pending.reject(new Error(message.error));\n }\n return;\n }\n case \"watch.update\": {\n const watchKey = this.watchKeyBySubscriptionId.get(\n message.subscriptionId\n );\n if (!watchKey) {\n return;\n }\n const watchRecord = this.watchRecordsByKey.get(watchKey);\n if (!watchRecord) {\n return;\n }\n if (message.success) {\n watchRecord.result = message.value;\n watchRecord.error = undefined;\n } else {\n watchRecord.error = new Error(message.error);\n }\n for (const listener of watchRecord.listeners) {\n listener();\n }\n }\n }\n };\n\n constructor(private readonly endpoint: SyncoreBridgeMessageEndpoint) {\n this.endpoint.addEventListener(\"message\", this.handleMessage);\n this.endpoint.postMessage({ type: \"runtime.status.request\" });\n }\n\n query<TArgs, TResult>(\n reference: FunctionReference<\"query\", TArgs, TResult>,\n ...args: OptionalArgsTuple<TArgs>\n ): Promise<TResult> {\n return this.invoke(\"query\", reference, normalizeOptionalArgs(args) as JsonObject);\n }\n\n mutation<TArgs, TResult>(\n reference: FunctionReference<\"mutation\", TArgs, TResult>,\n ...args: OptionalArgsTuple<TArgs>\n ): Promise<TResult> {\n return this.invoke(\n \"mutation\",\n reference,\n normalizeOptionalArgs(args) as JsonObject\n );\n }\n\n action<TArgs, TResult>(\n reference: FunctionReference<\"action\", TArgs, TResult>,\n ...args: OptionalArgsTuple<TArgs>\n ): Promise<TResult> {\n return this.invoke(\n \"action\",\n reference,\n normalizeOptionalArgs(args) as JsonObject\n );\n }\n\n watchQuery<TArgs, TResult>(\n reference: FunctionReference<\"query\", TArgs, TResult>,\n ...args: OptionalArgsTuple<TArgs>\n ): BridgeQueryWatch<TResult> {\n this.ensureNotDisposed();\n const normalizedArgs = normalizeOptionalArgs(args) as JsonObject;\n const watchKey = createWatchKey(reference, normalizedArgs);\n let watchRecord = this.watchRecordsByKey.get(watchKey);\n if (!watchRecord) {\n watchRecord = {\n subscriptionId: generateId(),\n listeners: new Set<() => void>(),\n consumers: 0,\n result: undefined,\n error: undefined\n };\n this.watchRecordsByKey.set(watchKey, watchRecord);\n this.watchKeyBySubscriptionId.set(watchRecord.subscriptionId, watchKey);\n this.endpoint.postMessage({\n type: \"watch.subscribe\",\n subscriptionId: watchRecord.subscriptionId,\n reference,\n args: normalizedArgs\n } satisfies SyncoreBridgeRequest);\n }\n\n watchRecord.consumers += 1;\n let disposed = false;\n const ownedListeners = new Set<() => void>();\n\n return {\n onUpdate: (callback: () => void) => {\n watchRecord.listeners.add(callback);\n ownedListeners.add(callback);\n queueMicrotask(callback);\n return () => {\n watchRecord.listeners.delete(callback);\n ownedListeners.delete(callback);\n };\n },\n localQueryResult: () => watchRecord.result as TResult | undefined,\n localQueryError: () => watchRecord.error,\n dispose: () => {\n if (disposed) {\n return;\n }\n disposed = true;\n for (const callback of ownedListeners) {\n watchRecord.listeners.delete(callback);\n }\n ownedListeners.clear();\n watchRecord.consumers = Math.max(0, watchRecord.consumers - 1);\n if (watchRecord.consumers > 0) {\n return;\n }\n this.endpoint.postMessage({\n type: \"watch.unsubscribe\",\n subscriptionId: watchRecord.subscriptionId\n } satisfies SyncoreBridgeRequest);\n this.watchKeyBySubscriptionId.delete(watchRecord.subscriptionId);\n this.watchRecordsByKey.delete(watchKey);\n }\n };\n }\n\n watchRuntimeStatus(): SyncoreWatch<SyncoreRuntimeStatus> {\n return this.runtimeStatus.watch();\n }\n\n dispose(errorMessage = \"Syncore bridge client was disposed.\"): void {\n if (this.disposed) {\n return;\n }\n this.disposed = true;\n this.runtimeStatus.setStatus({\n kind: \"unavailable\",\n reason: \"disposed\",\n error: new Error(errorMessage)\n });\n this.endpoint.removeEventListener(\"message\", this.handleMessage);\n for (const watchRecord of this.watchRecordsByKey.values()) {\n this.endpoint.postMessage({\n type: \"watch.unsubscribe\",\n subscriptionId: watchRecord.subscriptionId\n } satisfies SyncoreBridgeRequest);\n }\n this.watchKeyBySubscriptionId.clear();\n this.watchRecordsByKey.clear();\n this.rejectAllPending(new Error(errorMessage));\n }\n\n private invoke<TArgs, TResult>(\n kind: \"query\" | \"mutation\" | \"action\",\n reference: FunctionReference<\n \"query\" | \"mutation\" | \"action\",\n TArgs,\n TResult\n >,\n args: JsonObject\n ): Promise<TResult> {\n this.ensureNotDisposed();\n const requestId = generateId();\n const promise = new Promise<TResult>((resolve, reject) => {\n this.pendingRequests.set(requestId, { resolve, reject });\n });\n\n this.endpoint.postMessage(\n createInvokeRequest(requestId, kind, reference, args)\n );\n\n return promise;\n }\n\n private rejectAllPending(error: Error): void {\n for (const pending of this.pendingRequests.values()) {\n pending.reject(error);\n }\n this.pendingRequests.clear();\n }\n\n private ensureNotDisposed(): void {\n if (this.disposed) {\n throw new Error(\"Syncore bridge client was disposed.\");\n }\n }\n}\n\nexport function createUnavailableSyncoreClient(\n status: SyncoreRuntimeStatus\n): SyncoreClient {\n const runtimeStatus = new RuntimeStatusController(status);\n const error =\n status.error ??\n new Error(\n status.reason\n ? `Syncore client is unavailable (${status.reason}).`\n : \"Syncore client is unavailable.\"\n );\n\n return {\n query: async () => Promise.reject(error),\n mutation: async () => Promise.reject(error),\n action: async () => Promise.reject(error),\n watchQuery: () => ({\n onUpdate: (callback) => {\n queueMicrotask(callback);\n return () => undefined;\n },\n localQueryResult: () => undefined,\n localQueryError: () => undefined\n }),\n watchRuntimeStatus: () => runtimeStatus.watch()\n };\n}\n\nexport function createDeferredSyncoreClient(options: {\n loadClient: () => Promise<SyncoreClient>;\n initialStatus?: SyncoreRuntimeStatus;\n failureReason?: SyncoreRuntimeStatus[\"reason\"];\n}): SyncoreClient {\n const runtimeStatus = new RuntimeStatusController(\n options.initialStatus ?? {\n kind: \"starting\",\n reason: \"booting\"\n }\n );\n const resolvedFailureReason = options.failureReason ?? \"runtime-unavailable\";\n let currentClient: SyncoreClient | undefined;\n let detachStatusListener: (() => void) | undefined;\n\n const clientPromise = Promise.resolve()\n .then(() => options.loadClient())\n .then((client) => {\n currentClient = client;\n const statusWatch = client.watchRuntimeStatus();\n const syncStatus = () => {\n const nextStatus = statusWatch.localQueryResult();\n if (nextStatus) {\n runtimeStatus.setStatus(nextStatus);\n }\n };\n syncStatus();\n detachStatusListener = statusWatch.onUpdate(syncStatus);\n return client;\n })\n .catch((error) => {\n const resolvedError =\n error instanceof Error ? error : new Error(String(error));\n runtimeStatus.setStatus({\n kind: \"error\",\n reason: resolvedFailureReason,\n error: resolvedError\n });\n throw resolvedError;\n });\n\n const waitForClient = () => clientPromise;\n\n return {\n query: async (reference, ...args) =>\n waitForClient().then((client) => client.query(reference, ...args)),\n mutation: async (reference, ...args) =>\n waitForClient().then((client) => client.mutation(reference, ...args)),\n action: async (reference, ...args) =>\n waitForClient().then((client) => client.action(reference, ...args)),\n watchQuery(reference, ...args) {\n let innerWatch: SyncoreWatch<unknown> | undefined;\n let detachInner: (() => void) | undefined;\n let result: unknown;\n let error: Error | undefined;\n const listeners = new Set<() => void>();\n let disposed = false;\n\n const notify = () => {\n for (const listener of listeners) {\n listener();\n }\n };\n\n void waitForClient()\n .then((client) => {\n if (disposed) {\n return;\n }\n innerWatch = client.watchQuery(reference, ...args);\n const sync = () => {\n result = innerWatch?.localQueryResult();\n error = innerWatch?.localQueryError();\n notify();\n };\n sync();\n detachInner = innerWatch.onUpdate(sync);\n })\n .catch((nextError) => {\n error = undefined;\n notify();\n });\n\n return {\n onUpdate(callback) {\n listeners.add(callback);\n queueMicrotask(callback);\n return () => {\n listeners.delete(callback);\n };\n },\n localQueryResult: () => result as typeof reference.__result | undefined,\n localQueryError: () => error,\n dispose() {\n if (disposed) {\n return;\n }\n disposed = true;\n detachInner?.();\n innerWatch?.dispose?.();\n listeners.clear();\n }\n };\n },\n watchRuntimeStatus: () => runtimeStatus.watch()\n };\n}\n\nexport interface AttachRuntimeBridgeOptions<\n TSchema extends SyncoreSchema<any>\n> {\n endpoint: SyncoreBridgeMessageEndpoint;\n createRuntime:\n | (() => Promise<SyncoreRuntime<TSchema>>)\n | (() => SyncoreRuntime<TSchema>);\n}\n\nexport interface AttachedRuntimeBridge {\n ready: Promise<void>;\n dispose(): Promise<void>;\n}\n\nexport function attachRuntimeBridge<\n TSchema extends SyncoreSchema<any>\n>(\n options: AttachRuntimeBridgeOptions<TSchema>\n): AttachedRuntimeBridge {\n const subscriptions = new Map<\n string,\n {\n watch: SyncoreWatch<unknown>;\n unsubscribe: () => void;\n }\n >();\n let latestStatus: SyncoreRuntimeStatus = {\n kind: \"starting\",\n reason: \"booting\"\n };\n\n const sendStatus = (status: SyncoreRuntimeStatus) => {\n latestStatus = status;\n options.endpoint.postMessage({\n type: \"runtime.status\",\n status\n } satisfies SyncoreBridgeResponse);\n };\n\n const runtimePromise = Promise.resolve(options.createRuntime()).then(\n async (runtime) => {\n await runtime.start();\n return runtime;\n }\n );\n\n const clientPromise = runtimePromise.then((runtime) => runtime.createClient());\n\n const ready = clientPromise\n .then(() => {\n sendStatus({\n kind: \"ready\"\n });\n options.endpoint.postMessage({\n type: \"runtime.ready\"\n } satisfies SyncoreBridgeResponse);\n })\n .catch((error) => {\n sendStatus({\n kind: \"error\",\n reason: \"runtime-unavailable\",\n ...(error instanceof Error ? { error } : {})\n });\n options.endpoint.postMessage({\n type: \"runtime.error\",\n error: error instanceof Error ? error.message : String(error)\n } satisfies SyncoreBridgeResponse);\n throw error;\n });\n\n const handleMessage = (event: MessageEvent<unknown>) => {\n void (async () => {\n const message = event.data as SyncoreBridgeRequest;\n if (!message || typeof message !== \"object\" || !(\"type\" in message)) {\n return;\n }\n\n if (message.type === \"runtime.status.request\") {\n sendStatus(latestStatus);\n return;\n }\n\n try {\n const client = await clientPromise;\n switch (message.type) {\n case \"invoke\": {\n const value =\n message.kind === \"query\"\n ? await client.query(message.reference, message.args)\n : message.kind === \"mutation\"\n ? await client.mutation(message.reference, message.args)\n : await client.action(message.reference, message.args);\n options.endpoint.postMessage({\n type: \"invoke.result\",\n requestId: message.requestId,\n success: true,\n value\n } satisfies SyncoreBridgeResponse);\n return;\n }\n case \"watch.subscribe\": {\n if (subscriptions.has(message.subscriptionId)) {\n return;\n }\n const watch = client.watchQuery(message.reference, message.args);\n const sendCurrentState = () => {\n const error = watch.localQueryError();\n if (error) {\n options.endpoint.postMessage({\n type: \"watch.update\",\n subscriptionId: message.subscriptionId,\n success: false,\n error: error.message\n } satisfies SyncoreBridgeResponse);\n return;\n }\n options.endpoint.postMessage({\n type: \"watch.update\",\n subscriptionId: message.subscriptionId,\n success: true,\n value: watch.localQueryResult()\n } satisfies SyncoreBridgeResponse);\n };\n const unsubscribe = watch.onUpdate(sendCurrentState);\n subscriptions.set(message.subscriptionId, { watch, unsubscribe });\n sendCurrentState();\n return;\n }\n case \"watch.unsubscribe\": {\n const subscription = subscriptions.get(message.subscriptionId);\n if (!subscription) {\n return;\n }\n subscription.unsubscribe();\n subscription.watch.dispose?.();\n subscriptions.delete(message.subscriptionId);\n }\n }\n } catch (error) {\n const errorMessage =\n error instanceof Error ? error.message : String(error);\n if (message.type === \"invoke\") {\n options.endpoint.postMessage({\n type: \"invoke.result\",\n requestId: message.requestId,\n success: false,\n error: errorMessage\n } satisfies SyncoreBridgeResponse);\n }\n if (message.type === \"watch.subscribe\") {\n options.endpoint.postMessage({\n type: \"watch.update\",\n subscriptionId: message.subscriptionId,\n success: false,\n error: errorMessage\n } satisfies SyncoreBridgeResponse);\n }\n }\n })();\n };\n\n options.endpoint.addEventListener(\"message\", handleMessage);\n sendStatus({\n kind: \"starting\",\n reason: \"booting\"\n });\n\n return {\n ready,\n async dispose() {\n sendStatus({\n kind: \"unavailable\",\n reason: \"disposed\"\n });\n options.endpoint.removeEventListener(\"message\", handleMessage);\n for (const subscription of subscriptions.values()) {\n subscription.unsubscribe();\n subscription.watch.dispose?.();\n }\n subscriptions.clear();\n const runtime = await runtimePromise;\n await runtime.stop();\n }\n };\n}\n\nexport function createInvokeRequest(\n requestId: string,\n kind: \"query\" | \"mutation\" | \"action\",\n reference:\n | FunctionReference<\"query\", unknown, unknown>\n | FunctionReference<\"mutation\", unknown, unknown>\n | FunctionReference<\"action\", unknown, unknown>,\n args: JsonObject\n): SyncoreBridgeRequest {\n switch (kind) {\n case \"query\":\n return {\n type: \"invoke\",\n requestId,\n kind,\n reference: reference as FunctionReference<\"query\">,\n args\n };\n case \"mutation\":\n return {\n type: \"invoke\",\n requestId,\n kind,\n reference: reference as FunctionReference<\"mutation\">,\n args\n };\n case \"action\":\n return {\n type: \"invoke\",\n requestId,\n kind,\n reference: reference as FunctionReference<\"action\">,\n args\n };\n }\n}\n\nexport function createWatchKey(\n reference: FunctionReference<\"query\", unknown, unknown>,\n args: JsonObject\n): string {\n return `${reference.name}:${stableStringify(args)}`;\n}\n\nexport function normalizeOptionalArgs<TArgs>(\n args: [] | [TArgs] | readonly unknown[]\n): TArgs {\n return (args[0] ?? {}) as TArgs;\n}\n\nexport function stableStringify(value: unknown): string {\n return JSON.stringify(sortValue(value));\n}\n\nfunction sortValue(value: unknown): unknown {\n if (Array.isArray(value)) {\n return value.map(sortValue);\n }\n if (value && typeof value === \"object\") {\n return Object.fromEntries(\n Object.entries(value as Record<string, unknown>)\n .sort(([left], [right]) => left.localeCompare(right))\n .map(([key, nested]) => [key, sortValue(nested)])\n );\n }\n return value;\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"transport.mjs","names":[],"sources":["../src/transport.ts"],"sourcesContent":["import {\n type SyncoreClient,\n type SyncoreRuntime,\n type JsonObject,\n type SyncoreRuntimeStatus,\n type SyncoreWatch\n} from \"./runtime/runtime.js\";\nimport type { SyncoreSchema } from \"@syncore/schema\";\nimport { generateId } from \"./runtime/id.js\";\nimport type { FunctionReference } from \"./runtime/functions.js\";\nimport { RuntimeStatusController } from \"./runtime/internal/runtimeStatus.js\";\n\nexport interface SyncoreBridgeMessageEndpoint {\n postMessage(message: unknown): void;\n addEventListener(\n type: \"message\",\n listener: (event: MessageEvent<unknown>) => void\n ): void;\n removeEventListener(\n type: \"message\",\n listener: (event: MessageEvent<unknown>) => void\n ): void;\n}\n\nexport type SyncoreBridgeRequest =\n | {\n type: \"runtime.status.request\";\n }\n | {\n type: \"invoke\";\n requestId: string;\n kind: \"query\";\n reference: FunctionReference<\"query\", unknown, unknown>;\n args: JsonObject;\n }\n | {\n type: \"invoke\";\n requestId: string;\n kind: \"mutation\";\n reference: FunctionReference<\"mutation\", unknown, unknown>;\n args: JsonObject;\n }\n | {\n type: \"invoke\";\n requestId: string;\n kind: \"action\";\n reference: FunctionReference<\"action\", unknown, unknown>;\n args: JsonObject;\n }\n | {\n type: \"watch.subscribe\";\n subscriptionId: string;\n reference: FunctionReference<\"query\", unknown, unknown>;\n args: JsonObject;\n }\n | {\n type: \"watch.unsubscribe\";\n subscriptionId: string;\n };\n\nexport type SyncoreBridgeResponse =\n | { type: \"runtime.ready\" }\n | { type: \"runtime.error\"; error: string }\n | { type: \"runtime.status\"; status: SyncoreRuntimeStatus }\n | {\n type: \"invoke.result\";\n requestId: string;\n success: true;\n value: unknown;\n }\n | {\n type: \"invoke.result\";\n requestId: string;\n success: false;\n error: string;\n }\n | {\n type: \"watch.update\";\n subscriptionId: string;\n success: true;\n value: unknown;\n }\n | {\n type: \"watch.update\";\n subscriptionId: string;\n success: false;\n error: string;\n };\n\ntype PendingRequest = {\n resolve(value: unknown): void;\n reject(error: Error): void;\n};\n\ntype WatchRecord = {\n subscriptionId: string;\n listeners: Set<() => void>;\n consumers: number;\n result: unknown;\n error: Error | undefined;\n};\n\ntype OptionalArgsTuple<TArgs> =\n Record<never, never> extends TArgs ? [args?: TArgs] : [args: TArgs];\n\nexport type BridgeQueryWatch<TValue> = SyncoreWatch<TValue> & {\n dispose(): void;\n};\n\nexport class SyncoreBridgeClient implements SyncoreClient {\n private readonly pendingRequests = new Map<string, PendingRequest>();\n private readonly watchRecordsByKey = new Map<string, WatchRecord>();\n private readonly watchKeyBySubscriptionId = new Map<string, string>();\n private readonly runtimeStatus = new RuntimeStatusController({\n kind: \"starting\",\n reason: \"booting\"\n });\n private disposed = false;\n\n private readonly handleMessage = (event: MessageEvent<unknown>) => {\n const message = event.data as SyncoreBridgeResponse;\n if (!message || typeof message !== \"object\" || !(\"type\" in message)) {\n return;\n }\n\n switch (message.type) {\n case \"runtime.ready\": {\n const currentStatus = this.runtimeStatus.getStatus();\n this.runtimeStatus.setStatus({\n kind: \"ready\",\n ...(currentStatus.capabilities\n ? { capabilities: currentStatus.capabilities }\n : {})\n });\n return;\n }\n case \"runtime.error\": {\n const statusBeforeError = this.runtimeStatus.getStatus();\n this.runtimeStatus.setStatus({\n kind: \"error\",\n reason: \"runtime-unavailable\",\n ...(statusBeforeError.capabilities\n ? { capabilities: statusBeforeError.capabilities }\n : {}),\n error: new Error(message.error)\n });\n for (const watchRecord of this.watchRecordsByKey.values()) {\n for (const listener of watchRecord.listeners) {\n listener();\n }\n }\n this.rejectAllPending(new Error(message.error));\n return;\n }\n case \"runtime.status\":\n this.runtimeStatus.setStatus(message.status);\n for (const watchRecord of this.watchRecordsByKey.values()) {\n for (const listener of watchRecord.listeners) {\n listener();\n }\n }\n if (message.status.error) {\n this.rejectAllPending(message.status.error);\n }\n return;\n case \"invoke.result\": {\n const pending = this.pendingRequests.get(message.requestId);\n if (!pending) {\n return;\n }\n this.pendingRequests.delete(message.requestId);\n if (message.success) {\n pending.resolve(message.value);\n } else {\n pending.reject(new Error(message.error));\n }\n return;\n }\n case \"watch.update\": {\n const watchKey = this.watchKeyBySubscriptionId.get(\n message.subscriptionId\n );\n if (!watchKey) {\n return;\n }\n const watchRecord = this.watchRecordsByKey.get(watchKey);\n if (!watchRecord) {\n return;\n }\n if (message.success) {\n watchRecord.result = message.value;\n watchRecord.error = undefined;\n } else {\n watchRecord.error = new Error(message.error);\n }\n for (const listener of watchRecord.listeners) {\n listener();\n }\n }\n }\n };\n\n constructor(private readonly endpoint: SyncoreBridgeMessageEndpoint) {\n this.endpoint.addEventListener(\"message\", this.handleMessage);\n this.endpoint.postMessage({ type: \"runtime.status.request\" });\n }\n\n query<TArgs, TResult>(\n reference: FunctionReference<\"query\", TArgs, TResult>,\n ...args: OptionalArgsTuple<TArgs>\n ): Promise<TResult> {\n return this.invoke(\"query\", reference, normalizeOptionalArgs(args) as JsonObject);\n }\n\n mutation<TArgs, TResult>(\n reference: FunctionReference<\"mutation\", TArgs, TResult>,\n ...args: OptionalArgsTuple<TArgs>\n ): Promise<TResult> {\n return this.invoke(\n \"mutation\",\n reference,\n normalizeOptionalArgs(args) as JsonObject\n );\n }\n\n action<TArgs, TResult>(\n reference: FunctionReference<\"action\", TArgs, TResult>,\n ...args: OptionalArgsTuple<TArgs>\n ): Promise<TResult> {\n return this.invoke(\n \"action\",\n reference,\n normalizeOptionalArgs(args) as JsonObject\n );\n }\n\n watchQuery<TArgs, TResult>(\n reference: FunctionReference<\"query\", TArgs, TResult>,\n ...args: OptionalArgsTuple<TArgs>\n ): BridgeQueryWatch<TResult> {\n this.ensureNotDisposed();\n const normalizedArgs = normalizeOptionalArgs(args) as JsonObject;\n const watchKey = createWatchKey(reference, normalizedArgs);\n let watchRecord = this.watchRecordsByKey.get(watchKey);\n if (!watchRecord) {\n watchRecord = {\n subscriptionId: generateId(),\n listeners: new Set<() => void>(),\n consumers: 0,\n result: undefined,\n error: undefined\n };\n this.watchRecordsByKey.set(watchKey, watchRecord);\n this.watchKeyBySubscriptionId.set(watchRecord.subscriptionId, watchKey);\n this.endpoint.postMessage({\n type: \"watch.subscribe\",\n subscriptionId: watchRecord.subscriptionId,\n reference,\n args: normalizedArgs\n } satisfies SyncoreBridgeRequest);\n }\n\n watchRecord.consumers += 1;\n let disposed = false;\n const ownedListeners = new Set<() => void>();\n\n return {\n onUpdate: (callback: () => void) => {\n watchRecord.listeners.add(callback);\n ownedListeners.add(callback);\n queueMicrotask(callback);\n return () => {\n watchRecord.listeners.delete(callback);\n ownedListeners.delete(callback);\n };\n },\n localQueryResult: () => watchRecord.result as TResult | undefined,\n localQueryError: () => watchRecord.error,\n dispose: () => {\n if (disposed) {\n return;\n }\n disposed = true;\n for (const callback of ownedListeners) {\n watchRecord.listeners.delete(callback);\n }\n ownedListeners.clear();\n watchRecord.consumers = Math.max(0, watchRecord.consumers - 1);\n if (watchRecord.consumers > 0) {\n return;\n }\n this.endpoint.postMessage({\n type: \"watch.unsubscribe\",\n subscriptionId: watchRecord.subscriptionId\n } satisfies SyncoreBridgeRequest);\n this.watchKeyBySubscriptionId.delete(watchRecord.subscriptionId);\n this.watchRecordsByKey.delete(watchKey);\n }\n };\n }\n\n watchRuntimeStatus(): SyncoreWatch<SyncoreRuntimeStatus> {\n return this.runtimeStatus.watch();\n }\n\n dispose(errorMessage = \"Syncore bridge client was disposed.\"): void {\n if (this.disposed) {\n return;\n }\n this.disposed = true;\n this.runtimeStatus.setStatus({\n kind: \"unavailable\",\n reason: \"disposed\",\n error: new Error(errorMessage)\n });\n this.endpoint.removeEventListener(\"message\", this.handleMessage);\n for (const watchRecord of this.watchRecordsByKey.values()) {\n this.endpoint.postMessage({\n type: \"watch.unsubscribe\",\n subscriptionId: watchRecord.subscriptionId\n } satisfies SyncoreBridgeRequest);\n }\n this.watchKeyBySubscriptionId.clear();\n this.watchRecordsByKey.clear();\n this.rejectAllPending(new Error(errorMessage));\n }\n\n private invoke<TArgs, TResult>(\n kind: \"query\" | \"mutation\" | \"action\",\n reference: FunctionReference<\n \"query\" | \"mutation\" | \"action\",\n TArgs,\n TResult\n >,\n args: JsonObject\n ): Promise<TResult> {\n this.ensureNotDisposed();\n const requestId = generateId();\n const promise = new Promise<TResult>((resolve, reject) => {\n this.pendingRequests.set(requestId, { resolve, reject });\n });\n\n this.endpoint.postMessage(\n createInvokeRequest(requestId, kind, reference, args)\n );\n\n return promise;\n }\n\n private rejectAllPending(error: Error): void {\n for (const pending of this.pendingRequests.values()) {\n pending.reject(error);\n }\n this.pendingRequests.clear();\n }\n\n private ensureNotDisposed(): void {\n if (this.disposed) {\n throw new Error(\"Syncore bridge client was disposed.\");\n }\n }\n}\n\nexport function createUnavailableSyncoreClient(\n status: SyncoreRuntimeStatus\n): SyncoreClient {\n const runtimeStatus = new RuntimeStatusController(status);\n const error =\n status.error ??\n new Error(\n status.reason\n ? `Syncore client is unavailable (${status.reason}).`\n : \"Syncore client is unavailable.\"\n );\n\n return {\n query: async () => Promise.reject(error),\n mutation: async () => Promise.reject(error),\n action: async () => Promise.reject(error),\n watchQuery: () => ({\n onUpdate: (callback) => {\n queueMicrotask(callback);\n return () => undefined;\n },\n localQueryResult: () => undefined,\n localQueryError: () => undefined\n }),\n watchRuntimeStatus: () => runtimeStatus.watch()\n };\n}\n\nexport function createDeferredSyncoreClient(options: {\n loadClient: () => Promise<SyncoreClient>;\n initialStatus?: SyncoreRuntimeStatus;\n failureReason?: SyncoreRuntimeStatus[\"reason\"];\n}): SyncoreClient {\n const runtimeStatus = new RuntimeStatusController(\n options.initialStatus ?? {\n kind: \"starting\",\n reason: \"booting\"\n }\n );\n const resolvedFailureReason = options.failureReason ?? \"runtime-unavailable\";\n let currentClient: SyncoreClient | undefined;\n let detachStatusListener: (() => void) | undefined;\n\n const clientPromise = Promise.resolve()\n .then(() => options.loadClient())\n .then((client) => {\n currentClient = client;\n const statusWatch = client.watchRuntimeStatus();\n const syncStatus = () => {\n const nextStatus = statusWatch.localQueryResult();\n if (nextStatus) {\n runtimeStatus.setStatus(nextStatus);\n }\n };\n syncStatus();\n detachStatusListener = statusWatch.onUpdate(syncStatus);\n return client;\n })\n .catch((error) => {\n const resolvedError =\n error instanceof Error ? error : new Error(String(error));\n runtimeStatus.setStatus({\n kind: \"error\",\n reason: resolvedFailureReason,\n error: resolvedError\n });\n throw resolvedError;\n });\n\n const waitForClient = () => clientPromise;\n\n return {\n query: async (reference, ...args) =>\n waitForClient().then((client) => client.query(reference, ...args)),\n mutation: async (reference, ...args) =>\n waitForClient().then((client) => client.mutation(reference, ...args)),\n action: async (reference, ...args) =>\n waitForClient().then((client) => client.action(reference, ...args)),\n watchQuery(reference, ...args) {\n let innerWatch: SyncoreWatch<unknown> | undefined;\n let detachInner: (() => void) | undefined;\n let result: unknown;\n let error: Error | undefined;\n const listeners = new Set<() => void>();\n let disposed = false;\n\n const notify = () => {\n for (const listener of listeners) {\n listener();\n }\n };\n\n void waitForClient()\n .then((client) => {\n if (disposed) {\n return;\n }\n innerWatch = client.watchQuery(reference, ...args);\n const sync = () => {\n result = innerWatch?.localQueryResult();\n error = innerWatch?.localQueryError();\n notify();\n };\n sync();\n detachInner = innerWatch.onUpdate(sync);\n })\n .catch((nextError) => {\n error = undefined;\n notify();\n });\n\n return {\n onUpdate(callback) {\n listeners.add(callback);\n queueMicrotask(callback);\n return () => {\n listeners.delete(callback);\n };\n },\n localQueryResult: () => result as typeof reference.__result | undefined,\n localQueryError: () => error,\n dispose() {\n if (disposed) {\n return;\n }\n disposed = true;\n detachInner?.();\n innerWatch?.dispose?.();\n listeners.clear();\n }\n };\n },\n watchRuntimeStatus: () => runtimeStatus.watch()\n };\n}\n\nexport interface AttachRuntimeBridgeOptions<\n TSchema extends SyncoreSchema<any>\n> {\n endpoint: SyncoreBridgeMessageEndpoint;\n createRuntime:\n | (() => Promise<SyncoreRuntime<TSchema>>)\n | (() => SyncoreRuntime<TSchema>);\n}\n\nexport interface AttachedRuntimeBridge {\n ready: Promise<void>;\n dispose(): Promise<void>;\n}\n\nexport function attachRuntimeBridge<\n TSchema extends SyncoreSchema<any>\n>(\n options: AttachRuntimeBridgeOptions<TSchema>\n): AttachedRuntimeBridge {\n const subscriptions = new Map<\n string,\n {\n watch: SyncoreWatch<unknown>;\n unsubscribe: () => void;\n }\n >();\n let latestStatus: SyncoreRuntimeStatus = {\n kind: \"starting\",\n reason: \"booting\"\n };\n let runtimeStatusWatch: SyncoreWatch<SyncoreRuntimeStatus> | undefined;\n let detachRuntimeStatus: (() => void) | undefined;\n\n const sendStatus = (status: SyncoreRuntimeStatus) => {\n latestStatus = status;\n options.endpoint.postMessage({\n type: \"runtime.status\",\n status\n } satisfies SyncoreBridgeResponse);\n };\n\n const runtimePromise = Promise.resolve(options.createRuntime()).then(\n async (runtime) => {\n await runtime.start();\n return runtime;\n }\n );\n\n const clientPromise = runtimePromise.then((runtime) => {\n const client = runtime.createClient();\n runtimeStatusWatch = client.watchRuntimeStatus();\n const forwardRuntimeStatus = () => {\n const status = runtimeStatusWatch?.localQueryResult();\n if (status) {\n sendStatus(status);\n }\n };\n forwardRuntimeStatus();\n detachRuntimeStatus = runtimeStatusWatch.onUpdate(forwardRuntimeStatus);\n return client;\n });\n\n const ready = clientPromise\n .then(() => {\n if (latestStatus.kind !== \"ready\") {\n sendStatus({\n kind: \"ready\",\n ...(latestStatus.capabilities\n ? { capabilities: latestStatus.capabilities }\n : {})\n });\n }\n options.endpoint.postMessage({\n type: \"runtime.ready\"\n } satisfies SyncoreBridgeResponse);\n })\n .catch((error) => {\n sendStatus({\n kind: \"error\",\n reason: \"runtime-unavailable\",\n ...(error instanceof Error ? { error } : {})\n });\n options.endpoint.postMessage({\n type: \"runtime.error\",\n error: error instanceof Error ? error.message : String(error)\n } satisfies SyncoreBridgeResponse);\n throw error;\n });\n\n const handleMessage = (event: MessageEvent<unknown>) => {\n void (async () => {\n const message = event.data as SyncoreBridgeRequest;\n if (!message || typeof message !== \"object\" || !(\"type\" in message)) {\n return;\n }\n\n if (message.type === \"runtime.status.request\") {\n sendStatus(latestStatus);\n return;\n }\n\n try {\n const client = await clientPromise;\n switch (message.type) {\n case \"invoke\": {\n const value =\n message.kind === \"query\"\n ? await client.query(message.reference, message.args)\n : message.kind === \"mutation\"\n ? await client.mutation(message.reference, message.args)\n : await client.action(message.reference, message.args);\n options.endpoint.postMessage({\n type: \"invoke.result\",\n requestId: message.requestId,\n success: true,\n value\n } satisfies SyncoreBridgeResponse);\n return;\n }\n case \"watch.subscribe\": {\n if (subscriptions.has(message.subscriptionId)) {\n return;\n }\n const watch = client.watchQuery(message.reference, message.args);\n const sendCurrentState = () => {\n const error = watch.localQueryError();\n if (error) {\n options.endpoint.postMessage({\n type: \"watch.update\",\n subscriptionId: message.subscriptionId,\n success: false,\n error: error.message\n } satisfies SyncoreBridgeResponse);\n return;\n }\n options.endpoint.postMessage({\n type: \"watch.update\",\n subscriptionId: message.subscriptionId,\n success: true,\n value: watch.localQueryResult()\n } satisfies SyncoreBridgeResponse);\n };\n const unsubscribe = watch.onUpdate(sendCurrentState);\n subscriptions.set(message.subscriptionId, { watch, unsubscribe });\n sendCurrentState();\n return;\n }\n case \"watch.unsubscribe\": {\n const subscription = subscriptions.get(message.subscriptionId);\n if (!subscription) {\n return;\n }\n subscription.unsubscribe();\n subscription.watch.dispose?.();\n subscriptions.delete(message.subscriptionId);\n }\n }\n } catch (error) {\n const errorMessage =\n error instanceof Error ? error.message : String(error);\n if (message.type === \"invoke\") {\n options.endpoint.postMessage({\n type: \"invoke.result\",\n requestId: message.requestId,\n success: false,\n error: errorMessage\n } satisfies SyncoreBridgeResponse);\n }\n if (message.type === \"watch.subscribe\") {\n options.endpoint.postMessage({\n type: \"watch.update\",\n subscriptionId: message.subscriptionId,\n success: false,\n error: errorMessage\n } satisfies SyncoreBridgeResponse);\n }\n }\n })();\n };\n\n options.endpoint.addEventListener(\"message\", handleMessage);\n sendStatus({\n kind: \"starting\",\n reason: \"booting\"\n });\n\n return {\n ready,\n async dispose() {\n sendStatus({\n kind: \"unavailable\",\n reason: \"disposed\"\n });\n options.endpoint.removeEventListener(\"message\", handleMessage);\n for (const subscription of subscriptions.values()) {\n subscription.unsubscribe();\n subscription.watch.dispose?.();\n }\n subscriptions.clear();\n detachRuntimeStatus?.();\n runtimeStatusWatch?.dispose?.();\n const runtime = await runtimePromise;\n await runtime.stop();\n }\n };\n}\n\nexport function createInvokeRequest(\n requestId: string,\n kind: \"query\" | \"mutation\" | \"action\",\n reference:\n | FunctionReference<\"query\", unknown, unknown>\n | FunctionReference<\"mutation\", unknown, unknown>\n | FunctionReference<\"action\", unknown, unknown>,\n args: JsonObject\n): SyncoreBridgeRequest {\n switch (kind) {\n case \"query\":\n return {\n type: \"invoke\",\n requestId,\n kind,\n reference: reference as FunctionReference<\"query\">,\n args\n };\n case \"mutation\":\n return {\n type: \"invoke\",\n requestId,\n kind,\n reference: reference as FunctionReference<\"mutation\">,\n args\n };\n case \"action\":\n return {\n type: \"invoke\",\n requestId,\n kind,\n reference: reference as FunctionReference<\"action\">,\n args\n };\n }\n}\n\nexport function createWatchKey(\n reference: FunctionReference<\"query\", unknown, unknown>,\n args: JsonObject\n): string {\n return `${reference.name}:${stableStringify(args)}`;\n}\n\nexport function normalizeOptionalArgs<TArgs>(\n args: [] | [TArgs] | readonly unknown[]\n): TArgs {\n return (args[0] ?? {}) as TArgs;\n}\n\nexport function stableStringify(value: unknown): string {\n return JSON.stringify(sortValue(value));\n}\n\nfunction sortValue(value: unknown): unknown {\n if (Array.isArray(value)) {\n return value.map(sortValue);\n }\n if (value && typeof value === \"object\") {\n return Object.fromEntries(\n Object.entries(value as Record<string, unknown>)\n .sort(([left], [right]) => left.localeCompare(right))\n .map(([key, nested]) => [key, sortValue(nested)])\n );\n }\n return value;\n}\n"],"mappings":"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"}
|
|
@@ -179,6 +179,14 @@ interface SyncoreDevtoolsCapabilities {
|
|
|
179
179
|
mutate: boolean;
|
|
180
180
|
importExport: boolean;
|
|
181
181
|
};
|
|
182
|
+
storage?: {
|
|
183
|
+
browse: boolean;
|
|
184
|
+
download: boolean;
|
|
185
|
+
readRange?: boolean;
|
|
186
|
+
delete: boolean;
|
|
187
|
+
maxPreviewBytes?: number;
|
|
188
|
+
reason?: string;
|
|
189
|
+
};
|
|
182
190
|
scheduler?: {
|
|
183
191
|
read: boolean;
|
|
184
192
|
edit: boolean;
|
|
@@ -301,6 +309,23 @@ type SyncoreDevtoolsCommandPayload = {
|
|
|
301
309
|
} | {
|
|
302
310
|
kind: "sql.write";
|
|
303
311
|
query: string;
|
|
312
|
+
} | {
|
|
313
|
+
kind: "storage.list";
|
|
314
|
+
limit?: number;
|
|
315
|
+
offset?: number;
|
|
316
|
+
search?: string;
|
|
317
|
+
} | {
|
|
318
|
+
kind: "storage.access.create";
|
|
319
|
+
id: string;
|
|
320
|
+
purpose: "preview" | "download";
|
|
321
|
+
} | {
|
|
322
|
+
kind: "storage.readRange";
|
|
323
|
+
id: string;
|
|
324
|
+
offset: number;
|
|
325
|
+
length: number;
|
|
326
|
+
} | {
|
|
327
|
+
kind: "storage.delete";
|
|
328
|
+
id: string;
|
|
304
329
|
} | {
|
|
305
330
|
kind: "scheduler.cancel";
|
|
306
331
|
jobId: string;
|
|
@@ -333,6 +358,11 @@ type SyncoreDevtoolsSubscriptionPayload = {
|
|
|
333
358
|
kind: "scheduler.jobs";
|
|
334
359
|
} | {
|
|
335
360
|
kind: "functions.catalog";
|
|
361
|
+
} | {
|
|
362
|
+
kind: "storage.list";
|
|
363
|
+
limit?: number;
|
|
364
|
+
offset?: number;
|
|
365
|
+
search?: string;
|
|
336
366
|
} | {
|
|
337
367
|
kind: "sql.watch";
|
|
338
368
|
query: string;
|
|
@@ -378,6 +408,35 @@ type SyncoreDevtoolsCommandResultPayload = {
|
|
|
378
408
|
rowsAffected: number;
|
|
379
409
|
error?: string;
|
|
380
410
|
invalidationScopes: string[];
|
|
411
|
+
} | {
|
|
412
|
+
kind: "storage.list.result";
|
|
413
|
+
entries: StorageEntry[];
|
|
414
|
+
totalCount: number;
|
|
415
|
+
offset: number;
|
|
416
|
+
hasMore: boolean;
|
|
417
|
+
error?: string;
|
|
418
|
+
} | {
|
|
419
|
+
kind: "storage.access.create.result";
|
|
420
|
+
entry?: StorageEntry;
|
|
421
|
+
url?: string;
|
|
422
|
+
expiresAt?: number;
|
|
423
|
+
supportsRange?: boolean;
|
|
424
|
+
maxPreviewBytes?: number;
|
|
425
|
+
error?: string;
|
|
426
|
+
} | {
|
|
427
|
+
kind: "storage.readRange.result";
|
|
428
|
+
entry?: StorageEntry;
|
|
429
|
+
offset: number;
|
|
430
|
+
bytesRead: number;
|
|
431
|
+
done: boolean;
|
|
432
|
+
supportsRange: boolean;
|
|
433
|
+
base64?: string;
|
|
434
|
+
error?: string;
|
|
435
|
+
} | {
|
|
436
|
+
kind: "storage.delete.result";
|
|
437
|
+
success: boolean;
|
|
438
|
+
deleted: boolean;
|
|
439
|
+
error?: string;
|
|
381
440
|
} | {
|
|
382
441
|
kind: "scheduler.cancel.result";
|
|
383
442
|
success: boolean;
|
|
@@ -417,6 +476,13 @@ type SyncoreDevtoolsSubscriptionResultPayload = {
|
|
|
417
476
|
} | {
|
|
418
477
|
kind: "functions.catalog.result";
|
|
419
478
|
functions: FunctionDefinition[];
|
|
479
|
+
} | {
|
|
480
|
+
kind: "storage.list.result";
|
|
481
|
+
entries: StorageEntry[];
|
|
482
|
+
totalCount: number;
|
|
483
|
+
offset: number;
|
|
484
|
+
hasMore: boolean;
|
|
485
|
+
error?: string;
|
|
420
486
|
} | {
|
|
421
487
|
kind: "sql.watch.result";
|
|
422
488
|
columns: string[];
|
|
@@ -461,6 +527,14 @@ interface TableIndex {
|
|
|
461
527
|
fields: string[];
|
|
462
528
|
unique: boolean;
|
|
463
529
|
}
|
|
530
|
+
interface StorageEntry {
|
|
531
|
+
id: string;
|
|
532
|
+
createdAt: number;
|
|
533
|
+
fileName?: string;
|
|
534
|
+
contentType?: string;
|
|
535
|
+
size: number;
|
|
536
|
+
path: string;
|
|
537
|
+
}
|
|
464
538
|
interface SchedulerJob {
|
|
465
539
|
id: string;
|
|
466
540
|
functionName: string;
|
|
@@ -516,5 +590,5 @@ type SchedulerMisfirePolicy = {
|
|
|
516
590
|
windowMs: number;
|
|
517
591
|
};
|
|
518
592
|
//#endregion
|
|
519
|
-
export { DataFilter, DevtoolsPreview, DocumentChangePreview, ExecutionTrace, FunctionDefinition, InvalidationCause, SYNCORE_DEVTOOLS_MAX_SUPPORTED_PROTOCOL_VERSION, SYNCORE_DEVTOOLS_MIN_SUPPORTED_PROTOCOL_VERSION, SYNCORE_DEVTOOLS_PROTOCOL_VERSION, SchedulerJob, SchedulerMisfirePolicy, SchedulerRecurringDailySchedule, SchedulerRecurringIntervalSchedule, SchedulerRecurringSchedule, SchedulerRecurringWeeklySchedule, SyncoreActiveQueryInfo, SyncoreDevtoolsCapabilities, SyncoreDevtoolsClientMessage, SyncoreDevtoolsCommand, SyncoreDevtoolsCommandPayload, SyncoreDevtoolsCommandResultPayload, SyncoreDevtoolsEvent, SyncoreDevtoolsEventOrigin, SyncoreDevtoolsExternalChangeEvent, SyncoreDevtoolsMessage, SyncoreDevtoolsSubscribe, SyncoreDevtoolsSubscriptionPayload, SyncoreDevtoolsSubscriptionResultPayload, SyncoreDevtoolsUnsubscribe, SyncoreRuntimeSummary, TableField, TableIndex, TableSchema, VersionHandshake, createBasePublicId, createPublicId, createPublicRuntimeId, createPublicTargetId, isCompatibleVersionHandshake };
|
|
593
|
+
export { DataFilter, DevtoolsPreview, DocumentChangePreview, ExecutionTrace, FunctionDefinition, InvalidationCause, SYNCORE_DEVTOOLS_MAX_SUPPORTED_PROTOCOL_VERSION, SYNCORE_DEVTOOLS_MIN_SUPPORTED_PROTOCOL_VERSION, SYNCORE_DEVTOOLS_PROTOCOL_VERSION, SchedulerJob, SchedulerMisfirePolicy, SchedulerRecurringDailySchedule, SchedulerRecurringIntervalSchedule, SchedulerRecurringSchedule, SchedulerRecurringWeeklySchedule, StorageEntry, SyncoreActiveQueryInfo, SyncoreDevtoolsCapabilities, SyncoreDevtoolsClientMessage, SyncoreDevtoolsCommand, SyncoreDevtoolsCommandPayload, SyncoreDevtoolsCommandResultPayload, SyncoreDevtoolsEvent, SyncoreDevtoolsEventOrigin, SyncoreDevtoolsExternalChangeEvent, SyncoreDevtoolsMessage, SyncoreDevtoolsSubscribe, SyncoreDevtoolsSubscriptionPayload, SyncoreDevtoolsSubscriptionResultPayload, SyncoreDevtoolsUnsubscribe, SyncoreRuntimeSummary, TableField, TableIndex, TableSchema, VersionHandshake, createBasePublicId, createPublicId, createPublicRuntimeId, createPublicTargetId, isCompatibleVersionHandshake };
|
|
520
594
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","names":[],"sources":["../src/index.ts"],"mappings":";KAAY,0BAAA;AAAA,cAEC,iCAAA;AAAA,cACA,+CAAA;AAAA,cACA,+CAAA;AAAA,UAEI,gBAAA;EACf,eAAA;EACA,2BAAA;EACA,2BAAA;EACA,cAAA;AAAA;AAAA,iBAGc,4BAAA,CACd,SAAA,EAAW,IAAI,CACb,gBAAA;AAAA,
|
|
1
|
+
{"version":3,"file":"index.d.ts","names":[],"sources":["../src/index.ts"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":[],"sources":["../src/index.ts"],"sourcesContent":["export type SyncoreDevtoolsEventOrigin = \"runtime\" | \"dashboard\";\n\nexport const SYNCORE_DEVTOOLS_PROTOCOL_VERSION = 1;\nexport const SYNCORE_DEVTOOLS_MIN_SUPPORTED_PROTOCOL_VERSION = 1;\nexport const SYNCORE_DEVTOOLS_MAX_SUPPORTED_PROTOCOL_VERSION = 1;\n\nexport interface VersionHandshake {\n protocolVersion: number;\n minSupportedProtocolVersion: number;\n maxSupportedProtocolVersion: number;\n runtimeVersion?: string;\n}\n\nexport function isCompatibleVersionHandshake(\n handshake: Pick<\n VersionHandshake,\n \"protocolVersion\" | \"minSupportedProtocolVersion\" | \"maxSupportedProtocolVersion\"\n >\n): boolean {\n return (\n handshake.maxSupportedProtocolVersion >=\n SYNCORE_DEVTOOLS_MIN_SUPPORTED_PROTOCOL_VERSION &&\n handshake.minSupportedProtocolVersion <=\n SYNCORE_DEVTOOLS_MAX_SUPPORTED_PROTOCOL_VERSION &&\n handshake.protocolVersion >= handshake.minSupportedProtocolVersion &&\n handshake.protocolVersion <= handshake.maxSupportedProtocolVersion\n );\n}\n\ntype SyncoreDevtoolsEventBase = {\n runtimeId: string;\n timestamp: number;\n sequence?: number;\n origin?: SyncoreDevtoolsEventOrigin;\n};\n\nexport type DevtoolsPreview =\n | {\n kind: \"value\";\n value: unknown;\n truncated?: boolean;\n note?: string;\n }\n | {\n kind: \"error\";\n message: string;\n truncated?: boolean;\n };\n\nexport interface DocumentChangePreview {\n table: string;\n id: string;\n operation: \"insert\" | \"patch\" | \"replace\" | \"delete\";\n fields?: string[];\n beforePreview?: DevtoolsPreview;\n afterPreview?: DevtoolsPreview;\n}\n\nexport interface InvalidationCause {\n executionId?: string;\n reason: string;\n changedScopes: string[];\n matchedScopes: string[];\n}\n\nexport interface ExecutionTrace {\n executionId: string;\n parentExecutionId?: string;\n kind: \"query\" | \"mutation\" | \"action\" | \"scheduler\" | \"dashboard\";\n functionName?: string;\n argsPreview?: DevtoolsPreview;\n resultPreview?: DevtoolsPreview;\n error?: string;\n readScopes?: string[];\n writeScopes?: string[];\n changedScopes?: string[];\n changedDocumentsPreview?: DocumentChangePreview[];\n invalidatedQueryIds?: string[];\n schedulerJobId?: string;\n}\n\nexport type SyncoreDevtoolsEvent =\n | (SyncoreDevtoolsEventBase & {\n type: \"runtime.connected\";\n platform: string;\n })\n | (SyncoreDevtoolsEventBase & {\n type: \"runtime.disconnected\";\n })\n | (SyncoreDevtoolsEventBase & {\n type: \"query.executed\";\n queryId: string;\n functionName: string;\n componentPath?: string;\n componentName?: string;\n dependencies: string[];\n durationMs: number;\n executionId?: string;\n parentExecutionId?: string;\n argsPreview?: DevtoolsPreview;\n resultPreview?: DevtoolsPreview;\n readScopes?: string[];\n })\n | (SyncoreDevtoolsEventBase & {\n type: \"query.invalidated\";\n queryId: string;\n componentPath?: string;\n componentName?: string;\n reason: string;\n causedByExecutionId?: string;\n changedScopes?: string[];\n matchedScopes?: string[];\n rerunExecutionId?: string;\n })\n | (SyncoreDevtoolsEventBase & {\n type: \"mutation.committed\";\n mutationId: string;\n functionName: string;\n componentPath?: string;\n componentName?: string;\n changedTables: string[];\n durationMs: number;\n executionId?: string;\n parentExecutionId?: string;\n argsPreview?: DevtoolsPreview;\n resultPreview?: DevtoolsPreview;\n writeScopes?: string[];\n changedScopes?: string[];\n changedDocumentsPreview?: DocumentChangePreview[];\n invalidatedQueryIds?: string[];\n })\n | (SyncoreDevtoolsEventBase & {\n type: \"action.completed\";\n actionId: string;\n functionName: string;\n componentPath?: string;\n componentName?: string;\n durationMs: number;\n error?: string;\n executionId?: string;\n parentExecutionId?: string;\n argsPreview?: DevtoolsPreview;\n resultPreview?: DevtoolsPreview;\n writeScopes?: string[];\n changedScopes?: string[];\n changedDocumentsPreview?: DocumentChangePreview[];\n invalidatedQueryIds?: string[];\n })\n | (SyncoreDevtoolsEventBase & {\n type: \"scheduler.tick\";\n executedJobIds: string[];\n executionId?: string;\n jobExecutions?: Array<{\n jobId: string;\n executionId?: string;\n functionName: string;\n functionType: \"mutation\" | \"action\";\n argsPreview?: DevtoolsPreview;\n resultPreview?: DevtoolsPreview;\n error?: string;\n durationMs?: number;\n }>;\n })\n | (SyncoreDevtoolsEventBase & {\n type: \"storage.updated\";\n storageId: string;\n componentPath?: string;\n operation: \"put\" | \"delete\";\n })\n | (SyncoreDevtoolsEventBase & {\n type: \"log\";\n level: \"info\" | \"warn\" | \"error\";\n message: string;\n });\n\nexport interface SyncoreActiveQueryInfo {\n id: string;\n functionName: string;\n args?: Record<string, unknown>;\n consumers?: number;\n owner?: \"root\" | \"component\";\n componentPath?: string;\n componentName?: string;\n dependencyKeys: string[];\n lastRunAt: number;\n}\n\nexport interface SyncoreRuntimeSummary {\n runtimeId: string;\n platform: string;\n appName?: string;\n origin?: string;\n sessionLabel?: string;\n targetKind?: \"client\" | \"project\";\n runtimeRole?: \"app\" | \"project-target\";\n storageProtocol?: string;\n databaseLabel?: string;\n dataSourceAlias?: string;\n storageIdentity?: string;\n capabilities?: SyncoreDevtoolsCapabilities;\n connectedAt: number;\n activeQueryCount: number;\n recentEventCount: number;\n}\n\nexport interface SyncoreDevtoolsCapabilities {\n sql?: {\n read: boolean;\n write: boolean;\n live: boolean;\n reason?: string;\n };\n data?: {\n browse: boolean;\n mutate: boolean;\n importExport: boolean;\n };\n scheduler?: {\n read: boolean;\n edit: boolean;\n };\n}\n\nexport interface SyncoreDevtoolsExternalChangeEvent {\n sourceId: string;\n scope: \"database\" | \"storage\" | \"all\";\n reason: \"commit\" | \"storage-put\" | \"storage-delete\" | \"reconcile\";\n timestamp: number;\n revision?: string;\n changedScopes?: string[];\n changedTables?: string[];\n storageIds?: string[];\n}\n\nexport function createBasePublicId(input: string): string {\n return stablePublicId(input, 0);\n}\n\nexport function createPublicId(\n key: string,\n keys: Iterable<string>\n): string {\n return createPublicIdWithFormatter(key, keys, stablePublicId);\n}\n\nexport function createPublicRuntimeId(\n runtimeId: string,\n runtimeIds?: Iterable<string>\n): string {\n return runtimeIds\n ? createPublicIdWithFormatter(runtimeId, runtimeIds, stableRuntimePublicId)\n : stableRuntimePublicId(runtimeId, 0);\n}\n\nexport function createPublicTargetId(\n targetKey: string,\n targetKeys: Iterable<string>\n): string {\n return createPublicId(targetKey, targetKeys);\n}\n\nfunction createPublicIdWithFormatter(\n key: string,\n keys: Iterable<string>,\n formatPublicId: (input: string, salt: number) => string\n): string {\n const used = new Set<string>();\n for (const existingKey of [...keys].sort()) {\n let attempt = 0;\n while (true) {\n const candidate = formatPublicId(existingKey, attempt);\n if (existingKey === key && !used.has(candidate)) {\n return candidate;\n }\n if (!used.has(candidate)) {\n used.add(candidate);\n break;\n }\n attempt += 1;\n }\n }\n return formatPublicId(key, 0);\n}\n\nfunction stablePublicId(input: string, salt: number): string {\n const value = stableHash(input, salt) % 100000;\n return value.toString().padStart(5, \"0\");\n}\n\nfunction stableRuntimePublicId(input: string, salt: number): string {\n const value = stableHash(input, salt);\n const letter = String.fromCharCode(65 + (value % 26));\n const digits = Math.floor(value / 26) % 1000;\n return `${letter}${digits.toString().padStart(3, \"0\")}`;\n}\n\nfunction stableHash(input: string, salt: number): number {\n const hashInput = salt === 0 ? input : `${input}#${salt}`;\n let hash = 2166136261;\n for (let index = 0; index < hashInput.length; index += 1) {\n hash ^= hashInput.charCodeAt(index);\n hash = Math.imul(hash, 16777619);\n }\n return hash >>> 0;\n}\n\n/* ------------------------------------------------------------------ */\n/* Runtime → Dashboard messages */\n/* ------------------------------------------------------------------ */\n\nexport type SyncoreDevtoolsMessage =\n | {\n type: \"hello\";\n protocolVersion?: number;\n minSupportedProtocolVersion?: number;\n maxSupportedProtocolVersion?: number;\n runtimeVersion?: string;\n runtimeId: string;\n platform: string;\n appName?: string;\n origin?: string;\n sessionLabel?: string;\n targetKind?: \"client\" | \"project\";\n runtimeRole?: \"app\" | \"project-target\";\n storageProtocol?: string;\n databaseLabel?: string;\n dataSourceAlias?: string;\n storageIdentity?: string;\n capabilities?: SyncoreDevtoolsCapabilities;\n }\n | { type: \"event\"; event: SyncoreDevtoolsEvent }\n | {\n type: \"event.batch\";\n runtimeId: string;\n events: SyncoreDevtoolsEvent[];\n }\n | { type: \"ping\" }\n | { type: \"pong\" }\n | {\n type: \"command.result\";\n commandId: string;\n runtimeId: string;\n payload: SyncoreDevtoolsCommandResultPayload;\n }\n | {\n type: \"subscription.data\";\n subscriptionId: string;\n runtimeId: string;\n payload: SyncoreDevtoolsSubscriptionResultPayload;\n }\n | {\n type: \"subscription.error\";\n subscriptionId: string;\n runtimeId: string;\n error: string;\n }\n | {\n type: \"external.change\";\n runtimeId: string;\n storageIdentity: string;\n event: SyncoreDevtoolsExternalChangeEvent;\n };\n\n/* ------------------------------------------------------------------ */\n/* Dashboard → Runtime requests */\n/* ------------------------------------------------------------------ */\n\nexport interface SyncoreDevtoolsCommand {\n type: \"command\";\n commandId: string;\n targetRuntimeId: string;\n payload: SyncoreDevtoolsCommandPayload;\n}\n\nexport interface SyncoreDevtoolsSubscribe {\n type: \"subscribe\";\n subscriptionId: string;\n targetRuntimeId: string;\n payload: SyncoreDevtoolsSubscriptionPayload;\n}\n\nexport interface SyncoreDevtoolsUnsubscribe {\n type: \"unsubscribe\";\n subscriptionId: string;\n targetRuntimeId: string;\n}\n\nexport type SyncoreDevtoolsClientMessage =\n | { type: \"ping\" }\n | SyncoreDevtoolsCommand\n | SyncoreDevtoolsSubscribe\n | SyncoreDevtoolsUnsubscribe;\n\nexport type SyncoreDevtoolsCommandPayload =\n /* Functions */\n | {\n kind: \"fn.run\";\n functionName: string;\n functionType: \"query\" | \"mutation\" | \"action\";\n args: Record<string, unknown>;\n }\n | { kind: \"data.insert\"; table: string; document: Record<string, unknown> }\n | {\n kind: \"data.patch\";\n table: string;\n id: string;\n fields: Record<string, unknown>;\n }\n | { kind: \"data.delete\"; table: string; id: string }\n | { kind: \"data.export\"; tables?: string[] }\n | {\n kind: \"data.referenceOptions\";\n table: string;\n search?: string;\n limit?: number;\n offset?: number;\n }\n /* SQL */\n | { kind: \"sql.read\"; query: string }\n | { kind: \"sql.write\"; query: string }\n /* Scheduler */\n | { kind: \"scheduler.cancel\"; jobId: string }\n | {\n kind: \"scheduler.update\";\n jobId: string;\n schedule?: SchedulerRecurringSchedule;\n args: Record<string, unknown>;\n misfirePolicy?: SchedulerMisfirePolicy;\n runAt?: number;\n };\n\nexport type SyncoreDevtoolsSubscriptionPayload =\n | { kind: \"runtime.summary\" }\n | { kind: \"runtime.activeQueries\" }\n | { kind: \"schema.tables\" }\n | {\n kind: \"fn.watch\";\n functionName: string;\n functionType: \"query\";\n args: Record<string, unknown>;\n }\n | {\n kind: \"data.table\";\n table: string;\n filters?: DataFilter[];\n limit?: number;\n cursor?: string;\n }\n | { kind: \"scheduler.jobs\" }\n | { kind: \"functions.catalog\" }\n | { kind: \"sql.watch\"; query: string };\n\nexport interface DataFilter {\n field: string;\n operator:\n | \"eq\"\n | \"neq\"\n | \"gt\"\n | \"gte\"\n | \"lt\"\n | \"lte\"\n | \"contains\"\n | \"startsWith\";\n value: unknown;\n}\n\n/* ------------------------------------------------------------------ */\n/* Response payloads */\n/* ------------------------------------------------------------------ */\n\nexport type SyncoreDevtoolsCommandResultPayload =\n | {\n kind: \"fn.run.result\";\n result?: unknown;\n error?: string;\n durationMs: number;\n }\n | {\n kind: \"data.mutate.result\";\n success: boolean;\n id?: string;\n error?: string;\n }\n | {\n kind: \"data.export.result\";\n tables: Array<{\n name: string;\n rows: Record<string, unknown>[];\n totalCount: number;\n }>;\n error?: string;\n }\n | {\n kind: \"data.referenceOptions.result\";\n table: string;\n rows: Record<string, unknown>[];\n totalCount: number;\n offset: number;\n hasMore: boolean;\n error?: string;\n }\n | {\n kind: \"sql.read.result\";\n columns: string[];\n rows: unknown[][];\n error?: string;\n }\n | {\n kind: \"sql.write.result\";\n rowsAffected: number;\n error?: string;\n invalidationScopes: string[];\n }\n | {\n kind: \"scheduler.cancel.result\";\n success: boolean;\n cancelled: boolean;\n error?: string;\n }\n | {\n kind: \"scheduler.update.result\";\n success: boolean;\n updated: boolean;\n error?: string;\n job?: SchedulerJob;\n }\n | { kind: \"error\"; message: string };\n\nexport type SyncoreDevtoolsSubscriptionResultPayload =\n | { kind: \"runtime.summary.result\"; summary: SyncoreRuntimeSummary }\n | {\n kind: \"runtime.activeQueries.result\";\n activeQueries: SyncoreActiveQueryInfo[];\n }\n | {\n kind: \"fn.watch.result\";\n result?: unknown;\n error?: string;\n }\n | { kind: \"schema.tables.result\"; tables: TableSchema[] }\n | {\n kind: \"data.table.result\";\n rows: Record<string, unknown>[];\n totalCount: number;\n cursor?: string;\n }\n | { kind: \"scheduler.jobs.result\"; jobs: SchedulerJob[] }\n | { kind: \"functions.catalog.result\"; functions: FunctionDefinition[] }\n | {\n kind: \"sql.watch.result\";\n columns: string[];\n rows: unknown[][];\n observedTables: string[];\n };\n\n/* ------------------------------------------------------------------ */\n/* Shared data shapes */\n/* ------------------------------------------------------------------ */\n\nexport interface FunctionDefinition {\n name: string;\n type: \"query\" | \"mutation\" | \"action\";\n file?: string;\n modulePath?: string;\n namespace?: string;\n metadataAvailable?: boolean;\n owner?: \"root\" | \"component\";\n componentPath?: string;\n componentName?: string;\n visibility?: \"public\" | \"internal\";\n localName?: string;\n /** Argument validator schema (JSON Schema-like), if available */\n args?: Record<string, unknown>;\n /** Return validator schema, if available */\n returns?: Record<string, unknown>;\n}\n\nexport interface TableSchema {\n name: string;\n displayName?: string;\n owner?: \"root\" | \"component\";\n componentPath?: string;\n componentName?: string;\n fields: TableField[];\n indexes: TableIndex[];\n documentCount: number;\n}\n\nexport interface TableField {\n name: string;\n type: string;\n optional: boolean;\n referenceTable?: string;\n}\n\nexport interface TableIndex {\n name: string;\n fields: string[];\n unique: boolean;\n}\n\nexport interface SchedulerJob {\n id: string;\n functionName: string;\n owner?: \"root\" | \"component\";\n componentPath?: string;\n componentName?: string;\n args: Record<string, unknown>;\n scheduledAt: number;\n runAt: number;\n status: \"pending\" | \"running\" | \"completed\" | \"failed\" | \"cancelled\";\n completedAt?: number;\n result?: unknown;\n error?: string;\n durationMs?: number;\n recurringName?: string;\n schedule?: SchedulerRecurringSchedule;\n scheduleLabel?: string;\n misfirePolicy?: SchedulerMisfirePolicy;\n timezone?: string;\n lastRunAt?: number;\n updatedAt?: number;\n /** Compatibility label for older UI code. */\n cronSchedule?: string;\n}\n\nexport interface SchedulerRecurringIntervalSchedule {\n type: \"interval\";\n seconds?: number;\n minutes?: number;\n hours?: number;\n}\n\nexport interface SchedulerRecurringDailySchedule {\n type: \"daily\";\n hour: number;\n minute: number;\n timezone?: string;\n}\n\nexport interface SchedulerRecurringWeeklySchedule {\n type: \"weekly\";\n dayOfWeek:\n | \"sunday\"\n | \"monday\"\n | \"tuesday\"\n | \"wednesday\"\n | \"thursday\"\n | \"friday\"\n | \"saturday\";\n hour: number;\n minute: number;\n timezone?: string;\n}\n\nexport type SchedulerRecurringSchedule =\n | SchedulerRecurringIntervalSchedule\n | SchedulerRecurringDailySchedule\n | SchedulerRecurringWeeklySchedule;\n\nexport type SchedulerMisfirePolicy =\n | { type: \"catch_up\" }\n | { type: \"skip\" }\n | { type: \"run_once_if_missed\" }\n | { type: \"windowed\"; windowMs: number };\n"],"mappings":";AAEA,MAAa,oCAAoC;AACjD,MAAa,kDAAkD;AAC/D,MAAa,kDAAkD;AAS/D,SAAgB,6BACd,WAIS;CACT,OACE,UAAU,+BAAA,KAEV,UAAU,+BAAA,KAEV,UAAU,mBAAmB,UAAU,+BACvC,UAAU,mBAAmB,UAAU;AAE3C;AA+MA,SAAgB,mBAAmB,OAAuB;CACxD,OAAO,eAAe,OAAO,CAAC;AAChC;AAEA,SAAgB,eACd,KACA,MACQ;CACR,OAAO,4BAA4B,KAAK,MAAM,cAAc;AAC9D;AAEA,SAAgB,sBACd,WACA,YACQ;CACR,OAAO,aACH,4BAA4B,WAAW,YAAY,qBAAqB,IACxE,sBAAsB,WAAW,CAAC;AACxC;AAEA,SAAgB,qBACd,WACA,YACQ;CACR,OAAO,eAAe,WAAW,UAAU;AAC7C;AAEA,SAAS,4BACP,KACA,MACA,gBACQ;CACR,MAAM,uBAAO,IAAI,IAAY;CAC7B,KAAK,MAAM,eAAe,CAAC,GAAG,IAAI,EAAE,KAAK,GAAG;EAC1C,IAAI,UAAU;EACd,OAAO,MAAM;GACX,MAAM,YAAY,eAAe,aAAa,OAAO;GACrD,IAAI,gBAAgB,OAAO,CAAC,KAAK,IAAI,SAAS,GAC5C,OAAO;GAET,IAAI,CAAC,KAAK,IAAI,SAAS,GAAG;IACxB,KAAK,IAAI,SAAS;IAClB;GACF;GACA,WAAW;EACb;CACF;CACA,OAAO,eAAe,KAAK,CAAC;AAC9B;AAEA,SAAS,eAAe,OAAe,MAAsB;CAE3D,QADc,WAAW,OAAO,IAAI,IAAI,KAC3B,SAAS,EAAE,SAAS,GAAG,GAAG;AACzC;AAEA,SAAS,sBAAsB,OAAe,MAAsB;CAClE,MAAM,QAAQ,WAAW,OAAO,IAAI;CAGpC,OAAO,GAFQ,OAAO,aAAa,KAAM,QAAQ,EAElC,KADA,KAAK,MAAM,QAAQ,EAAE,IAAI,KACd,SAAS,EAAE,SAAS,GAAG,GAAG;AACtD;AAEA,SAAS,WAAW,OAAe,MAAsB;CACvD,MAAM,YAAY,SAAS,IAAI,QAAQ,GAAG,MAAM,GAAG;CACnD,IAAI,OAAO;CACX,KAAK,IAAI,QAAQ,GAAG,QAAQ,UAAU,QAAQ,SAAS,GAAG;EACxD,QAAQ,UAAU,WAAW,KAAK;EAClC,OAAO,KAAK,KAAK,MAAM,QAAQ;CACjC;CACA,OAAO,SAAS;AAClB"}
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../src/index.ts"],"sourcesContent":["export type SyncoreDevtoolsEventOrigin = \"runtime\" | \"dashboard\";\n\nexport const SYNCORE_DEVTOOLS_PROTOCOL_VERSION = 1;\nexport const SYNCORE_DEVTOOLS_MIN_SUPPORTED_PROTOCOL_VERSION = 1;\nexport const SYNCORE_DEVTOOLS_MAX_SUPPORTED_PROTOCOL_VERSION = 1;\n\nexport interface VersionHandshake {\n protocolVersion: number;\n minSupportedProtocolVersion: number;\n maxSupportedProtocolVersion: number;\n runtimeVersion?: string;\n}\n\nexport function isCompatibleVersionHandshake(\n handshake: Pick<\n VersionHandshake,\n | \"protocolVersion\"\n | \"minSupportedProtocolVersion\"\n | \"maxSupportedProtocolVersion\"\n >\n): boolean {\n return (\n handshake.maxSupportedProtocolVersion >=\n SYNCORE_DEVTOOLS_MIN_SUPPORTED_PROTOCOL_VERSION &&\n handshake.minSupportedProtocolVersion <=\n SYNCORE_DEVTOOLS_MAX_SUPPORTED_PROTOCOL_VERSION &&\n handshake.protocolVersion >= handshake.minSupportedProtocolVersion &&\n handshake.protocolVersion <= handshake.maxSupportedProtocolVersion\n );\n}\n\ntype SyncoreDevtoolsEventBase = {\n runtimeId: string;\n timestamp: number;\n sequence?: number;\n origin?: SyncoreDevtoolsEventOrigin;\n};\n\nexport type DevtoolsPreview =\n | {\n kind: \"value\";\n value: unknown;\n truncated?: boolean;\n note?: string;\n }\n | {\n kind: \"error\";\n message: string;\n truncated?: boolean;\n };\n\nexport interface DocumentChangePreview {\n table: string;\n id: string;\n operation: \"insert\" | \"patch\" | \"replace\" | \"delete\";\n fields?: string[];\n beforePreview?: DevtoolsPreview;\n afterPreview?: DevtoolsPreview;\n}\n\nexport interface InvalidationCause {\n executionId?: string;\n reason: string;\n changedScopes: string[];\n matchedScopes: string[];\n}\n\nexport interface ExecutionTrace {\n executionId: string;\n parentExecutionId?: string;\n kind: \"query\" | \"mutation\" | \"action\" | \"scheduler\" | \"dashboard\";\n functionName?: string;\n argsPreview?: DevtoolsPreview;\n resultPreview?: DevtoolsPreview;\n error?: string;\n readScopes?: string[];\n writeScopes?: string[];\n changedScopes?: string[];\n changedDocumentsPreview?: DocumentChangePreview[];\n invalidatedQueryIds?: string[];\n schedulerJobId?: string;\n}\n\nexport type SyncoreDevtoolsEvent =\n | (SyncoreDevtoolsEventBase & {\n type: \"runtime.connected\";\n platform: string;\n })\n | (SyncoreDevtoolsEventBase & {\n type: \"runtime.disconnected\";\n })\n | (SyncoreDevtoolsEventBase & {\n type: \"query.executed\";\n queryId: string;\n functionName: string;\n componentPath?: string;\n componentName?: string;\n dependencies: string[];\n durationMs: number;\n executionId?: string;\n parentExecutionId?: string;\n argsPreview?: DevtoolsPreview;\n resultPreview?: DevtoolsPreview;\n readScopes?: string[];\n })\n | (SyncoreDevtoolsEventBase & {\n type: \"query.invalidated\";\n queryId: string;\n componentPath?: string;\n componentName?: string;\n reason: string;\n causedByExecutionId?: string;\n changedScopes?: string[];\n matchedScopes?: string[];\n rerunExecutionId?: string;\n })\n | (SyncoreDevtoolsEventBase & {\n type: \"mutation.committed\";\n mutationId: string;\n functionName: string;\n componentPath?: string;\n componentName?: string;\n changedTables: string[];\n durationMs: number;\n executionId?: string;\n parentExecutionId?: string;\n argsPreview?: DevtoolsPreview;\n resultPreview?: DevtoolsPreview;\n writeScopes?: string[];\n changedScopes?: string[];\n changedDocumentsPreview?: DocumentChangePreview[];\n invalidatedQueryIds?: string[];\n })\n | (SyncoreDevtoolsEventBase & {\n type: \"action.completed\";\n actionId: string;\n functionName: string;\n componentPath?: string;\n componentName?: string;\n durationMs: number;\n error?: string;\n executionId?: string;\n parentExecutionId?: string;\n argsPreview?: DevtoolsPreview;\n resultPreview?: DevtoolsPreview;\n writeScopes?: string[];\n changedScopes?: string[];\n changedDocumentsPreview?: DocumentChangePreview[];\n invalidatedQueryIds?: string[];\n })\n | (SyncoreDevtoolsEventBase & {\n type: \"scheduler.tick\";\n executedJobIds: string[];\n executionId?: string;\n jobExecutions?: Array<{\n jobId: string;\n executionId?: string;\n functionName: string;\n functionType: \"mutation\" | \"action\";\n argsPreview?: DevtoolsPreview;\n resultPreview?: DevtoolsPreview;\n error?: string;\n durationMs?: number;\n }>;\n })\n | (SyncoreDevtoolsEventBase & {\n type: \"storage.updated\";\n storageId: string;\n componentPath?: string;\n operation: \"put\" | \"delete\";\n })\n | (SyncoreDevtoolsEventBase & {\n type: \"log\";\n level: \"info\" | \"warn\" | \"error\";\n message: string;\n });\n\nexport interface SyncoreActiveQueryInfo {\n id: string;\n functionName: string;\n args?: Record<string, unknown>;\n consumers?: number;\n owner?: \"root\" | \"component\";\n componentPath?: string;\n componentName?: string;\n dependencyKeys: string[];\n lastRunAt: number;\n}\n\nexport interface SyncoreRuntimeSummary {\n runtimeId: string;\n platform: string;\n appName?: string;\n origin?: string;\n sessionLabel?: string;\n targetKind?: \"client\" | \"project\";\n runtimeRole?: \"app\" | \"project-target\";\n storageProtocol?: string;\n databaseLabel?: string;\n dataSourceAlias?: string;\n storageIdentity?: string;\n capabilities?: SyncoreDevtoolsCapabilities;\n connectedAt: number;\n activeQueryCount: number;\n recentEventCount: number;\n}\n\nexport interface SyncoreDevtoolsCapabilities {\n sql?: {\n read: boolean;\n write: boolean;\n live: boolean;\n reason?: string;\n };\n data?: {\n browse: boolean;\n mutate: boolean;\n importExport: boolean;\n };\n storage?: {\n browse: boolean;\n download: boolean;\n readRange?: boolean;\n delete: boolean;\n maxPreviewBytes?: number;\n reason?: string;\n };\n scheduler?: {\n read: boolean;\n edit: boolean;\n };\n}\n\nexport interface SyncoreDevtoolsExternalChangeEvent {\n sourceId: string;\n scope: \"database\" | \"storage\" | \"all\";\n reason: \"commit\" | \"storage-put\" | \"storage-delete\" | \"reconcile\";\n timestamp: number;\n revision?: string;\n changedScopes?: string[];\n changedTables?: string[];\n storageIds?: string[];\n}\n\nexport function createBasePublicId(input: string): string {\n return stablePublicId(input, 0);\n}\n\nexport function createPublicId(key: string, keys: Iterable<string>): string {\n return createPublicIdWithFormatter(key, keys, stablePublicId);\n}\n\nexport function createPublicRuntimeId(\n runtimeId: string,\n runtimeIds?: Iterable<string>\n): string {\n return runtimeIds\n ? createPublicIdWithFormatter(runtimeId, runtimeIds, stableRuntimePublicId)\n : stableRuntimePublicId(runtimeId, 0);\n}\n\nexport function createPublicTargetId(\n targetKey: string,\n targetKeys: Iterable<string>\n): string {\n return createPublicId(targetKey, targetKeys);\n}\n\nfunction createPublicIdWithFormatter(\n key: string,\n keys: Iterable<string>,\n formatPublicId: (input: string, salt: number) => string\n): string {\n const used = new Set<string>();\n for (const existingKey of [...keys].sort()) {\n let attempt = 0;\n while (true) {\n const candidate = formatPublicId(existingKey, attempt);\n if (existingKey === key && !used.has(candidate)) {\n return candidate;\n }\n if (!used.has(candidate)) {\n used.add(candidate);\n break;\n }\n attempt += 1;\n }\n }\n return formatPublicId(key, 0);\n}\n\nfunction stablePublicId(input: string, salt: number): string {\n const value = stableHash(input, salt) % 100000;\n return value.toString().padStart(5, \"0\");\n}\n\nfunction stableRuntimePublicId(input: string, salt: number): string {\n const value = stableHash(input, salt);\n const letter = String.fromCharCode(65 + (value % 26));\n const digits = Math.floor(value / 26) % 1000;\n return `${letter}${digits.toString().padStart(3, \"0\")}`;\n}\n\nfunction stableHash(input: string, salt: number): number {\n const hashInput = salt === 0 ? input : `${input}#${salt}`;\n let hash = 2166136261;\n for (let index = 0; index < hashInput.length; index += 1) {\n hash ^= hashInput.charCodeAt(index);\n hash = Math.imul(hash, 16777619);\n }\n return hash >>> 0;\n}\n\n/* ------------------------------------------------------------------ */\n/* Runtime → Dashboard messages */\n/* ------------------------------------------------------------------ */\n\nexport type SyncoreDevtoolsMessage =\n | {\n type: \"hello\";\n protocolVersion?: number;\n minSupportedProtocolVersion?: number;\n maxSupportedProtocolVersion?: number;\n runtimeVersion?: string;\n runtimeId: string;\n platform: string;\n appName?: string;\n origin?: string;\n sessionLabel?: string;\n targetKind?: \"client\" | \"project\";\n runtimeRole?: \"app\" | \"project-target\";\n storageProtocol?: string;\n databaseLabel?: string;\n dataSourceAlias?: string;\n storageIdentity?: string;\n capabilities?: SyncoreDevtoolsCapabilities;\n }\n | { type: \"event\"; event: SyncoreDevtoolsEvent }\n | {\n type: \"event.batch\";\n runtimeId: string;\n events: SyncoreDevtoolsEvent[];\n }\n | { type: \"ping\" }\n | { type: \"pong\" }\n | {\n type: \"command.result\";\n commandId: string;\n runtimeId: string;\n payload: SyncoreDevtoolsCommandResultPayload;\n }\n | {\n type: \"subscription.data\";\n subscriptionId: string;\n runtimeId: string;\n payload: SyncoreDevtoolsSubscriptionResultPayload;\n }\n | {\n type: \"subscription.error\";\n subscriptionId: string;\n runtimeId: string;\n error: string;\n }\n | {\n type: \"external.change\";\n runtimeId: string;\n storageIdentity: string;\n event: SyncoreDevtoolsExternalChangeEvent;\n };\n\n/* ------------------------------------------------------------------ */\n/* Dashboard → Runtime requests */\n/* ------------------------------------------------------------------ */\n\nexport interface SyncoreDevtoolsCommand {\n type: \"command\";\n commandId: string;\n targetRuntimeId: string;\n payload: SyncoreDevtoolsCommandPayload;\n}\n\nexport interface SyncoreDevtoolsSubscribe {\n type: \"subscribe\";\n subscriptionId: string;\n targetRuntimeId: string;\n payload: SyncoreDevtoolsSubscriptionPayload;\n}\n\nexport interface SyncoreDevtoolsUnsubscribe {\n type: \"unsubscribe\";\n subscriptionId: string;\n targetRuntimeId: string;\n}\n\nexport type SyncoreDevtoolsClientMessage =\n | { type: \"ping\" }\n | SyncoreDevtoolsCommand\n | SyncoreDevtoolsSubscribe\n | SyncoreDevtoolsUnsubscribe;\n\nexport type SyncoreDevtoolsCommandPayload =\n /* Functions */\n | {\n kind: \"fn.run\";\n functionName: string;\n functionType: \"query\" | \"mutation\" | \"action\";\n args: Record<string, unknown>;\n }\n | { kind: \"data.insert\"; table: string; document: Record<string, unknown> }\n | {\n kind: \"data.patch\";\n table: string;\n id: string;\n fields: Record<string, unknown>;\n }\n | { kind: \"data.delete\"; table: string; id: string }\n | { kind: \"data.export\"; tables?: string[] }\n | {\n kind: \"data.referenceOptions\";\n table: string;\n search?: string;\n limit?: number;\n offset?: number;\n }\n /* SQL */\n | { kind: \"sql.read\"; query: string }\n | { kind: \"sql.write\"; query: string }\n /* Storage */\n | {\n kind: \"storage.list\";\n limit?: number;\n offset?: number;\n search?: string;\n }\n | {\n kind: \"storage.access.create\";\n id: string;\n purpose: \"preview\" | \"download\";\n }\n | {\n kind: \"storage.readRange\";\n id: string;\n offset: number;\n length: number;\n }\n | { kind: \"storage.delete\"; id: string }\n /* Scheduler */\n | { kind: \"scheduler.cancel\"; jobId: string }\n | {\n kind: \"scheduler.update\";\n jobId: string;\n schedule?: SchedulerRecurringSchedule;\n args: Record<string, unknown>;\n misfirePolicy?: SchedulerMisfirePolicy;\n runAt?: number;\n };\n\nexport type SyncoreDevtoolsSubscriptionPayload =\n | { kind: \"runtime.summary\" }\n | { kind: \"runtime.activeQueries\" }\n | { kind: \"schema.tables\" }\n | {\n kind: \"fn.watch\";\n functionName: string;\n functionType: \"query\";\n args: Record<string, unknown>;\n }\n | {\n kind: \"data.table\";\n table: string;\n filters?: DataFilter[];\n limit?: number;\n cursor?: string;\n }\n | { kind: \"scheduler.jobs\" }\n | { kind: \"functions.catalog\" }\n | {\n kind: \"storage.list\";\n limit?: number;\n offset?: number;\n search?: string;\n }\n | { kind: \"sql.watch\"; query: string };\n\nexport interface DataFilter {\n field: string;\n operator:\n | \"eq\"\n | \"neq\"\n | \"gt\"\n | \"gte\"\n | \"lt\"\n | \"lte\"\n | \"contains\"\n | \"startsWith\";\n value: unknown;\n}\n\n/* ------------------------------------------------------------------ */\n/* Response payloads */\n/* ------------------------------------------------------------------ */\n\nexport type SyncoreDevtoolsCommandResultPayload =\n | {\n kind: \"fn.run.result\";\n result?: unknown;\n error?: string;\n durationMs: number;\n }\n | {\n kind: \"data.mutate.result\";\n success: boolean;\n id?: string;\n error?: string;\n }\n | {\n kind: \"data.export.result\";\n tables: Array<{\n name: string;\n rows: Record<string, unknown>[];\n totalCount: number;\n }>;\n error?: string;\n }\n | {\n kind: \"data.referenceOptions.result\";\n table: string;\n rows: Record<string, unknown>[];\n totalCount: number;\n offset: number;\n hasMore: boolean;\n error?: string;\n }\n | {\n kind: \"sql.read.result\";\n columns: string[];\n rows: unknown[][];\n error?: string;\n }\n | {\n kind: \"sql.write.result\";\n rowsAffected: number;\n error?: string;\n invalidationScopes: string[];\n }\n | {\n kind: \"storage.list.result\";\n entries: StorageEntry[];\n totalCount: number;\n offset: number;\n hasMore: boolean;\n error?: string;\n }\n | {\n kind: \"storage.access.create.result\";\n entry?: StorageEntry;\n url?: string;\n expiresAt?: number;\n supportsRange?: boolean;\n maxPreviewBytes?: number;\n error?: string;\n }\n | {\n kind: \"storage.readRange.result\";\n entry?: StorageEntry;\n offset: number;\n bytesRead: number;\n done: boolean;\n supportsRange: boolean;\n base64?: string;\n error?: string;\n }\n | {\n kind: \"storage.delete.result\";\n success: boolean;\n deleted: boolean;\n error?: string;\n }\n | {\n kind: \"scheduler.cancel.result\";\n success: boolean;\n cancelled: boolean;\n error?: string;\n }\n | {\n kind: \"scheduler.update.result\";\n success: boolean;\n updated: boolean;\n error?: string;\n job?: SchedulerJob;\n }\n | { kind: \"error\"; message: string };\n\nexport type SyncoreDevtoolsSubscriptionResultPayload =\n | { kind: \"runtime.summary.result\"; summary: SyncoreRuntimeSummary }\n | {\n kind: \"runtime.activeQueries.result\";\n activeQueries: SyncoreActiveQueryInfo[];\n }\n | {\n kind: \"fn.watch.result\";\n result?: unknown;\n error?: string;\n }\n | { kind: \"schema.tables.result\"; tables: TableSchema[] }\n | {\n kind: \"data.table.result\";\n rows: Record<string, unknown>[];\n totalCount: number;\n cursor?: string;\n }\n | { kind: \"scheduler.jobs.result\"; jobs: SchedulerJob[] }\n | { kind: \"functions.catalog.result\"; functions: FunctionDefinition[] }\n | {\n kind: \"storage.list.result\";\n entries: StorageEntry[];\n totalCount: number;\n offset: number;\n hasMore: boolean;\n error?: string;\n }\n | {\n kind: \"sql.watch.result\";\n columns: string[];\n rows: unknown[][];\n observedTables: string[];\n };\n\n/* ------------------------------------------------------------------ */\n/* Shared data shapes */\n/* ------------------------------------------------------------------ */\n\nexport interface FunctionDefinition {\n name: string;\n type: \"query\" | \"mutation\" | \"action\";\n file?: string;\n modulePath?: string;\n namespace?: string;\n metadataAvailable?: boolean;\n owner?: \"root\" | \"component\";\n componentPath?: string;\n componentName?: string;\n visibility?: \"public\" | \"internal\";\n localName?: string;\n /** Argument validator schema (JSON Schema-like), if available */\n args?: Record<string, unknown>;\n /** Return validator schema, if available */\n returns?: Record<string, unknown>;\n}\n\nexport interface TableSchema {\n name: string;\n displayName?: string;\n owner?: \"root\" | \"component\";\n componentPath?: string;\n componentName?: string;\n fields: TableField[];\n indexes: TableIndex[];\n documentCount: number;\n}\n\nexport interface TableField {\n name: string;\n type: string;\n optional: boolean;\n referenceTable?: string;\n}\n\nexport interface TableIndex {\n name: string;\n fields: string[];\n unique: boolean;\n}\n\nexport interface StorageEntry {\n id: string;\n createdAt: number;\n fileName?: string;\n contentType?: string;\n size: number;\n path: string;\n}\n\nexport interface SchedulerJob {\n id: string;\n functionName: string;\n owner?: \"root\" | \"component\";\n componentPath?: string;\n componentName?: string;\n args: Record<string, unknown>;\n scheduledAt: number;\n runAt: number;\n status: \"pending\" | \"running\" | \"completed\" | \"failed\" | \"cancelled\";\n completedAt?: number;\n result?: unknown;\n error?: string;\n durationMs?: number;\n recurringName?: string;\n schedule?: SchedulerRecurringSchedule;\n scheduleLabel?: string;\n misfirePolicy?: SchedulerMisfirePolicy;\n timezone?: string;\n lastRunAt?: number;\n updatedAt?: number;\n /** Compatibility label for older UI code. */\n cronSchedule?: string;\n}\n\nexport interface SchedulerRecurringIntervalSchedule {\n type: \"interval\";\n seconds?: number;\n minutes?: number;\n hours?: number;\n}\n\nexport interface SchedulerRecurringDailySchedule {\n type: \"daily\";\n hour: number;\n minute: number;\n timezone?: string;\n}\n\nexport interface SchedulerRecurringWeeklySchedule {\n type: \"weekly\";\n dayOfWeek:\n | \"sunday\"\n | \"monday\"\n | \"tuesday\"\n | \"wednesday\"\n | \"thursday\"\n | \"friday\"\n | \"saturday\";\n hour: number;\n minute: number;\n timezone?: string;\n}\n\nexport type SchedulerRecurringSchedule =\n | SchedulerRecurringIntervalSchedule\n | SchedulerRecurringDailySchedule\n | SchedulerRecurringWeeklySchedule;\n\nexport type SchedulerMisfirePolicy =\n | { type: \"catch_up\" }\n | { type: \"skip\" }\n | { type: \"run_once_if_missed\" }\n | { type: \"windowed\"; windowMs: number };\n"],"mappings":";AAEA,MAAa,oCAAoC;AACjD,MAAa,kDAAkD;AAC/D,MAAa,kDAAkD;AAS/D,SAAgB,6BACd,WAMS;CACT,OACE,UAAU,+BAAA,KAEV,UAAU,+BAAA,KAEV,UAAU,mBAAmB,UAAU,+BACvC,UAAU,mBAAmB,UAAU;AAE3C;AAuNA,SAAgB,mBAAmB,OAAuB;CACxD,OAAO,eAAe,OAAO,CAAC;AAChC;AAEA,SAAgB,eAAe,KAAa,MAAgC;CAC1E,OAAO,4BAA4B,KAAK,MAAM,cAAc;AAC9D;AAEA,SAAgB,sBACd,WACA,YACQ;CACR,OAAO,aACH,4BAA4B,WAAW,YAAY,qBAAqB,IACxE,sBAAsB,WAAW,CAAC;AACxC;AAEA,SAAgB,qBACd,WACA,YACQ;CACR,OAAO,eAAe,WAAW,UAAU;AAC7C;AAEA,SAAS,4BACP,KACA,MACA,gBACQ;CACR,MAAM,uBAAO,IAAI,IAAY;CAC7B,KAAK,MAAM,eAAe,CAAC,GAAG,IAAI,EAAE,KAAK,GAAG;EAC1C,IAAI,UAAU;EACd,OAAO,MAAM;GACX,MAAM,YAAY,eAAe,aAAa,OAAO;GACrD,IAAI,gBAAgB,OAAO,CAAC,KAAK,IAAI,SAAS,GAC5C,OAAO;GAET,IAAI,CAAC,KAAK,IAAI,SAAS,GAAG;IACxB,KAAK,IAAI,SAAS;IAClB;GACF;GACA,WAAW;EACb;CACF;CACA,OAAO,eAAe,KAAK,CAAC;AAC9B;AAEA,SAAS,eAAe,OAAe,MAAsB;CAE3D,QADc,WAAW,OAAO,IAAI,IAAI,KAC3B,SAAS,EAAE,SAAS,GAAG,GAAG;AACzC;AAEA,SAAS,sBAAsB,OAAe,MAAsB;CAClE,MAAM,QAAQ,WAAW,OAAO,IAAI;CAGpC,OAAO,GAFQ,OAAO,aAAa,KAAM,QAAQ,EAElC,KADA,KAAK,MAAM,QAAQ,EAAE,IAAI,KACd,SAAS,EAAE,SAAS,GAAG,GAAG;AACtD;AAEA,SAAS,WAAW,OAAe,MAAsB;CACvD,MAAM,YAAY,SAAS,IAAI,QAAQ,GAAG,MAAM,GAAG;CACnD,IAAI,OAAO;CACX,KAAK,IAAI,QAAQ,GAAG,QAAQ,UAAU,QAAQ,SAAS,GAAG;EACxD,QAAQ,UAAU,WAAW,KAAK;EAClC,OAAO,KAAK,KAAK,MAAM,QAAQ;CACjC;CACA,OAAO,SAAS;AAClB"}
|
|
@@ -116,7 +116,11 @@ function SyncoreNextProvider({ children, createWorker, serviceWorkerUrl, workerU
|
|
|
116
116
|
const resolvedWorkerUrl = typeof workerUrl === "string" ? workerUrl : workerUrl?.toString();
|
|
117
117
|
const bootingClient = useMemo(() => createUnavailableSyncoreClient({
|
|
118
118
|
kind: "starting",
|
|
119
|
-
reason: "booting"
|
|
119
|
+
reason: "booting",
|
|
120
|
+
capabilities: { storage: {
|
|
121
|
+
available: false,
|
|
122
|
+
reason: "Syncore worker is booting."
|
|
123
|
+
} }
|
|
120
124
|
}), []);
|
|
121
125
|
const [client, setClient] = useState(bootingClient);
|
|
122
126
|
useEffect(() => {
|
|
@@ -134,6 +138,10 @@ function SyncoreNextProvider({ children, createWorker, serviceWorkerUrl, workerU
|
|
|
134
138
|
setClient(createUnavailableSyncoreClient({
|
|
135
139
|
kind: "unavailable",
|
|
136
140
|
reason: "worker-unavailable",
|
|
141
|
+
capabilities: { storage: {
|
|
142
|
+
available: false,
|
|
143
|
+
reason: "Syncore worker is unavailable."
|
|
144
|
+
} },
|
|
137
145
|
...error instanceof Error ? { error } : {}
|
|
138
146
|
}));
|
|
139
147
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":[],"sources":["../src/index.tsx"],"sourcesContent":["import {\n createUnavailableSyncoreClient,\n type SyncoreClient\n} from \"@syncore/core\";\nimport {\n createManagedWebWorkerClient,\n createSyncoreWebWorkerClient,\n type ManagedWebWorkerClient\n} from \"@syncore/platform-web\";\nimport { SyncoreProvider } from \"@syncore/react\";\nimport {\n useEffect,\n useMemo,\n useRef,\n useState,\n type ReactNode\n} from \"react\";\nimport { getSyncoreWorkerUrl } from \"./config.js\";\n\nexport { getSyncoreWorkerUrl } from \"./config.js\";\nexport { createSyncoreNextWorkerUrl } from \"./config.js\";\n\n/**\n * Shared configuration options for the Syncore Next.js integration.\n *\n * Accepted by both {@link SyncoreNextProvider} and\n * {@link registerSyncoreServiceWorker}.\n */\nexport interface SyncoreNextOptions {\n /**\n * URL of the Next PWA service worker. Defaults to `\"/sw.js\"` (the path\n * emitted by `next-pwa` or `@ducanh2912/next-pwa`).\n */\n serviceWorkerUrl?: string;\n\n /**\n * Public path to the compiled Syncore worker asset. Defaults to\n * `\"/syncore.worker.js\"`. Override if your build tool emits the worker to a\n * different path.\n */\n workerAssetUrl?: string;\n}\n\n/**\n * Handle returned by {@link registerSyncoreServiceWorker}.\n */\nexport interface SyncoreServiceWorkerRegistration {\n /** Unregister the installed service worker. */\n unregister(): Promise<boolean>;\n\n /**\n * Instruct the browser to check for a new service worker version. Useful\n * for implementing an “Update available” prompt.\n */\n update(): Promise<ServiceWorkerRegistration>;\n}\n\n/**\n * Register the Syncore PWA service worker in a Next.js app.\n *\n * Call this once at app startup (e.g. in your root layout’s `useEffect`, or in\n * `instrumentation.ts` with `\"use client\"`). Returns `null` on the server or\n * when the browser does not support service workers.\n *\n * ```ts\n * // app/layout.tsx (client component)\n * import { registerSyncoreServiceWorker } from \"syncorejs/next\";\n *\n * useEffect(() => {\n * registerSyncoreServiceWorker({ serviceWorkerUrl: \"/sw.js\" });\n * }, []);\n * ```\n *\n * @param options - Optional configuration. Defaults to `\"/sw.js\"`.\n * @returns A {@link SyncoreServiceWorkerRegistration} handle, or `null` on\n * the server / when unsupported.\n */\nexport async function registerSyncoreServiceWorker(\n options?: SyncoreNextOptions\n): Promise<SyncoreServiceWorkerRegistration | null> {\n if (typeof window === \"undefined\" || !(\"serviceWorker\" in navigator)) {\n return null;\n }\n\n const registration = await navigator.serviceWorker.register(\n options?.serviceWorkerUrl ?? \"/sw.js\"\n );\n\n return {\n unregister: () => registration.unregister(),\n update: () => registration.update()\n };\n}\n\n/**\n * Create a worker-backed Syncore client for a Next.js app.\n *\n * The client communicates with a Syncore runtime running inside a `Worker`.\n * The worker runs the SQLite engine and all function handlers off the main\n * thread so the UI stays responsive.\n *\n * In most cases you should use {@link SyncoreNextProvider} instead, which\n * manages the client lifecycle automatically. Use `createNextSyncoreClient`\n * directly only when you need to control the client lifecycle yourself (e.g.\n * in testing harnesses or custom providers).\n *\n * ```ts\n * const managedClient = createNextSyncoreClient({\n * workerAssetUrl: \"/syncore.worker.js\",\n * });\n *\n * // Later:\n * managedClient.dispose();\n * ```\n */\nexport function createNextSyncoreClient(options: {\n /**\n * Custom worker factory function. Useful in tests (supply a `Worker` backed\n * by a mock or in-process runtime) or when using Next’s App Router dev-mode\n * bundling where `new Worker(new URL(...))` must be used inside the component.\n */\n createWorker?: () => Worker;\n\n /** Explicit module URL for an already-public worker script. */\n workerUrl?: URL | string;\n\n /** Public asset path for the compiled worker file. Defaults to `\"/syncore.worker.js\"`. */\n workerAssetUrl?: string;\n}): ManagedWebWorkerClient {\n if (options.createWorker) {\n return createManagedWebWorkerClient({\n createWorker: options.createWorker\n });\n }\n\n return createSyncoreWebWorkerClient({\n workerUrl:\n options.workerUrl ?? options.workerAssetUrl ?? \"/syncore.worker.js\"\n });\n}\n\n/**\n * React component that registers a PWA service worker as a side-effect.\n *\n * Renders its `children` immediately (no loading state) and registers the\n * service worker asynchronously. Safe to render on the server — the\n * registration effect only runs in browsers that support service workers.\n *\n * ```tsx\n * <SyncoreServiceWorker serviceWorkerUrl=\"/sw.js\" onRegistered={console.log}>\n * <App />\n * </SyncoreServiceWorker>\n * ```\n */\nexport function SyncoreServiceWorker({\n children,\n serviceWorkerUrl,\n onRegistered\n}: {\n children: ReactNode;\n /** URL of the service worker script. Defaults to `\"/sw.js\"`. */\n serviceWorkerUrl?: string;\n /** Called after the service worker is successfully registered. */\n onRegistered?: (registration: ServiceWorkerRegistration) => void;\n}) {\n useEffect(() => {\n void (async () => {\n if (typeof window === \"undefined\" || !(\"serviceWorker\" in navigator)) {\n return;\n }\n const registration = await navigator.serviceWorker.register(\n serviceWorkerUrl ?? \"/sw.js\"\n );\n onRegistered?.(registration);\n })();\n }, [onRegistered, serviceWorkerUrl]);\n\n return children;\n}\n\n/**\n * Root provider that wires a worker-backed Syncore runtime into a Next.js\n * React tree.\n *\n * Place this at the top of your App Router layout. It spawns the Syncore\n * worker on mount, exposes the client via React context (accessible with\n * `useSyncore()`), and optionally registers the PWA service worker.\n *\n * ```tsx\n * // app/layout.tsx\n * import { SyncoreNextProvider } from \"syncorejs/next\";\n *\n * export default function RootLayout({ children }) {\n * return (\n * <html>\n * <body>\n * <SyncoreNextProvider\n * createWorker={() => new Worker(\n * new URL(\"../syncore.worker.ts\", import.meta.url)\n * )}\n * >\n * {children}\n * </SyncoreNextProvider>\n * </body>\n * </html>\n * );\n * }\n * ```\n */\nexport function SyncoreNextProvider({\n children,\n createWorker,\n serviceWorkerUrl,\n workerUrl,\n workerAssetUrl\n}: {\n /** The React subtree that should receive the Syncore client. */\n children: ReactNode;\n\n /**\n * Factory function that creates the Syncore `Worker`. Required in Next App\n * Router dev mode because `new Worker(new URL(..., import.meta.url))` must\n * be called inside the module to be bundled correctly.\n */\n createWorker?: () => Worker;\n\n /** URL of the PWA service worker script. Omit to skip service worker registration. */\n serviceWorkerUrl?: string;\n\n /** Explicit module URL for an already-public worker asset. */\n workerUrl?: URL | string;\n\n /** Public asset path for the compiled worker file. Defaults to `\"/syncore.worker.js\"`. */\n workerAssetUrl?: string;\n}) {\n const createWorkerRef = useRef(createWorker);\n createWorkerRef.current = createWorker;\n const resolvedWorkerUrl =\n typeof workerUrl === \"string\" ? workerUrl : workerUrl?.toString();\n const bootingClient = useMemo(\n () =>\n createUnavailableSyncoreClient({\n kind: \"starting\",\n reason: \"booting\"\n }),\n []\n );\n const [client, setClient] = useState<SyncoreClient>(bootingClient);\n\n useEffect(() => {\n let managedClient: ManagedWebWorkerClient | undefined;\n\n setClient(bootingClient);\n\n try {\n const workerFactory = createWorkerRef.current;\n managedClient = createNextSyncoreClient({\n ...(workerFactory\n ? {\n createWorker: () => workerFactory()\n }\n : {}),\n ...(resolvedWorkerUrl\n ? {\n workerUrl:\n process.env.NODE_ENV === \"production\"\n ? getSyncoreWorkerUrl()\n : resolvedWorkerUrl\n }\n : {}),\n ...(workerAssetUrl ? { workerAssetUrl } : {})\n });\n setClient(managedClient.client);\n } catch (error) {\n setClient(\n createUnavailableSyncoreClient({\n kind: \"unavailable\",\n reason: \"worker-unavailable\",\n ...(error instanceof Error ? { error } : {})\n })\n );\n }\n\n return () => {\n managedClient?.dispose();\n };\n }, [bootingClient, resolvedWorkerUrl, workerAssetUrl]);\n\n return (\n <SyncoreServiceWorker {...(serviceWorkerUrl ? { serviceWorkerUrl } : {})}>\n <SyncoreProvider client={client}>{children}</SyncoreProvider>\n </SyncoreServiceWorker>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;AA6EA,eAAsB,6BACpB,SACkD;CAClD,IAAI,OAAO,WAAW,eAAe,EAAE,mBAAmB,YACxD,OAAO;CAGT,MAAM,eAAe,MAAM,UAAU,cAAc,SACjD,SAAS,oBAAoB,QAC/B;CAEA,OAAO;EACL,kBAAkB,aAAa,WAAW;EAC1C,cAAc,aAAa,OAAO;CACpC;AACF;;;;;;;;;;;;;;;;;;;;;;AAuBA,SAAgB,wBAAwB,SAab;CACzB,IAAI,QAAQ,cACV,OAAO,6BAA6B,EAClC,cAAc,QAAQ,aACxB,CAAC;CAGH,OAAO,6BAA6B,EAClC,WACE,QAAQ,aAAa,QAAQ,kBAAkB,qBACnD,CAAC;AACH;;;;;;;;;;;;;;AAeA,SAAgB,qBAAqB,EACnC,UACA,kBACA,gBAOC;CACD,gBAAgB;EACd,CAAM,YAAY;GAChB,IAAI,OAAO,WAAW,eAAe,EAAE,mBAAmB,YACxD;GAEF,MAAM,eAAe,MAAM,UAAU,cAAc,SACjD,oBAAoB,QACtB;GACA,eAAe,YAAY;EAC7B,GAAG;CACL,GAAG,CAAC,cAAc,gBAAgB,CAAC;CAEnC,OAAO;AACT;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA+BA,SAAgB,oBAAoB,EAClC,UACA,cACA,kBACA,WACA,kBAoBC;CACD,MAAM,kBAAkB,OAAO,YAAY;CAC3C,gBAAgB,UAAU;CAC1B,MAAM,oBACJ,OAAO,cAAc,WAAW,YAAY,WAAW,SAAS;CAClE,MAAM,gBAAgB,cAElB,+BAA+B;EAC7B,MAAM;EACN,QAAQ;CACV,CAAC,GACH,CAAC,CACH;CACA,MAAM,CAAC,QAAQ,aAAa,SAAwB,aAAa;CAEjE,gBAAgB;EACd,IAAI;EAEJ,UAAU,aAAa;EAEvB,IAAI;GACF,MAAM,gBAAgB,gBAAgB;GACtC,gBAAgB,wBAAwB;IACtC,GAAI,gBACA,EACE,oBAAoB,cAAc,EACpC,IACA,CAAC;IACL,GAAI,oBACA,EACE,WACE,QAAQ,IAAI,aAAa,eACrB,oBAAoB,IACpB,kBACR,IACA,CAAC;IACL,GAAI,iBAAiB,EAAE,eAAe,IAAI,CAAC;GAC7C,CAAC;GACD,UAAU,cAAc,MAAM;EAChC,SAAS,OAAO;GACd,UACE,+BAA+B;IAC7B,MAAM;IACN,QAAQ;IACR,GAAI,iBAAiB,QAAQ,EAAE,MAAM,IAAI,CAAC;GAC5C,CAAC,CACH;EACF;EAEA,aAAa;GACX,eAAe,QAAQ;EACzB;CACF,GAAG;EAAC;EAAe;EAAmB;CAAc,CAAC;CAErD,OACE,oBAAC,sBAAD;EAAsB,GAAK,mBAAmB,EAAE,iBAAiB,IAAI,CAAC;YACpE,oBAAC,iBAAD;GAAyB;GAAS;EAA0B,CAAA;CACxC,CAAA;AAE1B"}
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../src/index.tsx"],"sourcesContent":["import {\n createUnavailableSyncoreClient,\n type SyncoreClient\n} from \"@syncore/core\";\nimport {\n createManagedWebWorkerClient,\n createSyncoreWebWorkerClient,\n type ManagedWebWorkerClient\n} from \"@syncore/platform-web\";\nimport { SyncoreProvider } from \"@syncore/react\";\nimport {\n useEffect,\n useMemo,\n useRef,\n useState,\n type ReactNode\n} from \"react\";\nimport { getSyncoreWorkerUrl } from \"./config.js\";\n\nexport { getSyncoreWorkerUrl } from \"./config.js\";\nexport { createSyncoreNextWorkerUrl } from \"./config.js\";\n\n/**\n * Shared configuration options for the Syncore Next.js integration.\n *\n * Accepted by both {@link SyncoreNextProvider} and\n * {@link registerSyncoreServiceWorker}.\n */\nexport interface SyncoreNextOptions {\n /**\n * URL of the Next PWA service worker. Defaults to `\"/sw.js\"` (the path\n * emitted by `next-pwa` or `@ducanh2912/next-pwa`).\n */\n serviceWorkerUrl?: string;\n\n /**\n * Public path to the compiled Syncore worker asset. Defaults to\n * `\"/syncore.worker.js\"`. Override if your build tool emits the worker to a\n * different path.\n */\n workerAssetUrl?: string;\n}\n\n/**\n * Handle returned by {@link registerSyncoreServiceWorker}.\n */\nexport interface SyncoreServiceWorkerRegistration {\n /** Unregister the installed service worker. */\n unregister(): Promise<boolean>;\n\n /**\n * Instruct the browser to check for a new service worker version. Useful\n * for implementing an “Update available” prompt.\n */\n update(): Promise<ServiceWorkerRegistration>;\n}\n\n/**\n * Register the Syncore PWA service worker in a Next.js app.\n *\n * Call this once at app startup (e.g. in your root layout’s `useEffect`, or in\n * `instrumentation.ts` with `\"use client\"`). Returns `null` on the server or\n * when the browser does not support service workers.\n *\n * ```ts\n * // app/layout.tsx (client component)\n * import { registerSyncoreServiceWorker } from \"syncorejs/next\";\n *\n * useEffect(() => {\n * registerSyncoreServiceWorker({ serviceWorkerUrl: \"/sw.js\" });\n * }, []);\n * ```\n *\n * @param options - Optional configuration. Defaults to `\"/sw.js\"`.\n * @returns A {@link SyncoreServiceWorkerRegistration} handle, or `null` on\n * the server / when unsupported.\n */\nexport async function registerSyncoreServiceWorker(\n options?: SyncoreNextOptions\n): Promise<SyncoreServiceWorkerRegistration | null> {\n if (typeof window === \"undefined\" || !(\"serviceWorker\" in navigator)) {\n return null;\n }\n\n const registration = await navigator.serviceWorker.register(\n options?.serviceWorkerUrl ?? \"/sw.js\"\n );\n\n return {\n unregister: () => registration.unregister(),\n update: () => registration.update()\n };\n}\n\n/**\n * Create a worker-backed Syncore client for a Next.js app.\n *\n * The client communicates with a Syncore runtime running inside a `Worker`.\n * The worker runs the SQLite engine and all function handlers off the main\n * thread so the UI stays responsive.\n *\n * In most cases you should use {@link SyncoreNextProvider} instead, which\n * manages the client lifecycle automatically. Use `createNextSyncoreClient`\n * directly only when you need to control the client lifecycle yourself (e.g.\n * in testing harnesses or custom providers).\n *\n * ```ts\n * const managedClient = createNextSyncoreClient({\n * workerAssetUrl: \"/syncore.worker.js\",\n * });\n *\n * // Later:\n * managedClient.dispose();\n * ```\n */\nexport function createNextSyncoreClient(options: {\n /**\n * Custom worker factory function. Useful in tests (supply a `Worker` backed\n * by a mock or in-process runtime) or when using Next’s App Router dev-mode\n * bundling where `new Worker(new URL(...))` must be used inside the component.\n */\n createWorker?: () => Worker;\n\n /** Explicit module URL for an already-public worker script. */\n workerUrl?: URL | string;\n\n /** Public asset path for the compiled worker file. Defaults to `\"/syncore.worker.js\"`. */\n workerAssetUrl?: string;\n}): ManagedWebWorkerClient {\n if (options.createWorker) {\n return createManagedWebWorkerClient({\n createWorker: options.createWorker\n });\n }\n\n return createSyncoreWebWorkerClient({\n workerUrl:\n options.workerUrl ?? options.workerAssetUrl ?? \"/syncore.worker.js\"\n });\n}\n\n/**\n * React component that registers a PWA service worker as a side-effect.\n *\n * Renders its `children` immediately (no loading state) and registers the\n * service worker asynchronously. Safe to render on the server — the\n * registration effect only runs in browsers that support service workers.\n *\n * ```tsx\n * <SyncoreServiceWorker serviceWorkerUrl=\"/sw.js\" onRegistered={console.log}>\n * <App />\n * </SyncoreServiceWorker>\n * ```\n */\nexport function SyncoreServiceWorker({\n children,\n serviceWorkerUrl,\n onRegistered\n}: {\n children: ReactNode;\n /** URL of the service worker script. Defaults to `\"/sw.js\"`. */\n serviceWorkerUrl?: string;\n /** Called after the service worker is successfully registered. */\n onRegistered?: (registration: ServiceWorkerRegistration) => void;\n}) {\n useEffect(() => {\n void (async () => {\n if (typeof window === \"undefined\" || !(\"serviceWorker\" in navigator)) {\n return;\n }\n const registration = await navigator.serviceWorker.register(\n serviceWorkerUrl ?? \"/sw.js\"\n );\n onRegistered?.(registration);\n })();\n }, [onRegistered, serviceWorkerUrl]);\n\n return children;\n}\n\n/**\n * Root provider that wires a worker-backed Syncore runtime into a Next.js\n * React tree.\n *\n * Place this at the top of your App Router layout. It spawns the Syncore\n * worker on mount, exposes the client via React context (accessible with\n * `useSyncore()`), and optionally registers the PWA service worker.\n *\n * ```tsx\n * // app/layout.tsx\n * import { SyncoreNextProvider } from \"syncorejs/next\";\n *\n * export default function RootLayout({ children }) {\n * return (\n * <html>\n * <body>\n * <SyncoreNextProvider\n * createWorker={() => new Worker(\n * new URL(\"../syncore.worker.ts\", import.meta.url)\n * )}\n * >\n * {children}\n * </SyncoreNextProvider>\n * </body>\n * </html>\n * );\n * }\n * ```\n */\nexport function SyncoreNextProvider({\n children,\n createWorker,\n serviceWorkerUrl,\n workerUrl,\n workerAssetUrl\n}: {\n /** The React subtree that should receive the Syncore client. */\n children: ReactNode;\n\n /**\n * Factory function that creates the Syncore `Worker`. Required in Next App\n * Router dev mode because `new Worker(new URL(..., import.meta.url))` must\n * be called inside the module to be bundled correctly.\n */\n createWorker?: () => Worker;\n\n /** URL of the PWA service worker script. Omit to skip service worker registration. */\n serviceWorkerUrl?: string;\n\n /** Explicit module URL for an already-public worker asset. */\n workerUrl?: URL | string;\n\n /** Public asset path for the compiled worker file. Defaults to `\"/syncore.worker.js\"`. */\n workerAssetUrl?: string;\n}) {\n const createWorkerRef = useRef(createWorker);\n createWorkerRef.current = createWorker;\n const resolvedWorkerUrl =\n typeof workerUrl === \"string\" ? workerUrl : workerUrl?.toString();\n const bootingClient = useMemo(\n () =>\n createUnavailableSyncoreClient({\n kind: \"starting\",\n reason: \"booting\",\n capabilities: {\n storage: { available: false, reason: \"Syncore worker is booting.\" }\n }\n }),\n []\n );\n const [client, setClient] = useState<SyncoreClient>(bootingClient);\n\n useEffect(() => {\n let managedClient: ManagedWebWorkerClient | undefined;\n\n setClient(bootingClient);\n\n try {\n const workerFactory = createWorkerRef.current;\n managedClient = createNextSyncoreClient({\n ...(workerFactory\n ? {\n createWorker: () => workerFactory()\n }\n : {}),\n ...(resolvedWorkerUrl\n ? {\n workerUrl:\n process.env.NODE_ENV === \"production\"\n ? getSyncoreWorkerUrl()\n : resolvedWorkerUrl\n }\n : {}),\n ...(workerAssetUrl ? { workerAssetUrl } : {})\n });\n setClient(managedClient.client);\n } catch (error) {\n setClient(\n createUnavailableSyncoreClient({\n kind: \"unavailable\",\n reason: \"worker-unavailable\",\n capabilities: {\n storage: {\n available: false,\n reason: \"Syncore worker is unavailable.\"\n }\n },\n ...(error instanceof Error ? { error } : {})\n })\n );\n }\n\n return () => {\n managedClient?.dispose();\n };\n }, [bootingClient, resolvedWorkerUrl, workerAssetUrl]);\n\n return (\n <SyncoreServiceWorker {...(serviceWorkerUrl ? { serviceWorkerUrl } : {})}>\n <SyncoreProvider client={client}>{children}</SyncoreProvider>\n </SyncoreServiceWorker>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;AA6EA,eAAsB,6BACpB,SACkD;CAClD,IAAI,OAAO,WAAW,eAAe,EAAE,mBAAmB,YACxD,OAAO;CAGT,MAAM,eAAe,MAAM,UAAU,cAAc,SACjD,SAAS,oBAAoB,QAC/B;CAEA,OAAO;EACL,kBAAkB,aAAa,WAAW;EAC1C,cAAc,aAAa,OAAO;CACpC;AACF;;;;;;;;;;;;;;;;;;;;;;AAuBA,SAAgB,wBAAwB,SAab;CACzB,IAAI,QAAQ,cACV,OAAO,6BAA6B,EAClC,cAAc,QAAQ,aACxB,CAAC;CAGH,OAAO,6BAA6B,EAClC,WACE,QAAQ,aAAa,QAAQ,kBAAkB,qBACnD,CAAC;AACH;;;;;;;;;;;;;;AAeA,SAAgB,qBAAqB,EACnC,UACA,kBACA,gBAOC;CACD,gBAAgB;EACd,CAAM,YAAY;GAChB,IAAI,OAAO,WAAW,eAAe,EAAE,mBAAmB,YACxD;GAEF,MAAM,eAAe,MAAM,UAAU,cAAc,SACjD,oBAAoB,QACtB;GACA,eAAe,YAAY;EAC7B,GAAG;CACL,GAAG,CAAC,cAAc,gBAAgB,CAAC;CAEnC,OAAO;AACT;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA+BA,SAAgB,oBAAoB,EAClC,UACA,cACA,kBACA,WACA,kBAoBC;CACD,MAAM,kBAAkB,OAAO,YAAY;CAC3C,gBAAgB,UAAU;CAC1B,MAAM,oBACJ,OAAO,cAAc,WAAW,YAAY,WAAW,SAAS;CAClE,MAAM,gBAAgB,cAElB,+BAA+B;EAC7B,MAAM;EACN,QAAQ;EACR,cAAc,EACZ,SAAS;GAAE,WAAW;GAAO,QAAQ;EAA6B,EACpE;CACF,CAAC,GACH,CAAC,CACH;CACA,MAAM,CAAC,QAAQ,aAAa,SAAwB,aAAa;CAEjE,gBAAgB;EACd,IAAI;EAEJ,UAAU,aAAa;EAEvB,IAAI;GACF,MAAM,gBAAgB,gBAAgB;GACtC,gBAAgB,wBAAwB;IACtC,GAAI,gBACA,EACE,oBAAoB,cAAc,EACpC,IACA,CAAC;IACL,GAAI,oBACA,EACE,WACE,QAAQ,IAAI,aAAa,eACrB,oBAAoB,IACpB,kBACR,IACA,CAAC;IACL,GAAI,iBAAiB,EAAE,eAAe,IAAI,CAAC;GAC7C,CAAC;GACD,UAAU,cAAc,MAAM;EAChC,SAAS,OAAO;GACd,UACE,+BAA+B;IAC7B,MAAM;IACN,QAAQ;IACR,cAAc,EACZ,SAAS;KACP,WAAW;KACX,QAAQ;IACV,EACF;IACA,GAAI,iBAAiB,QAAQ,EAAE,MAAM,IAAI,CAAC;GAC5C,CAAC,CACH;EACF;EAEA,aAAa;GACX,eAAe,QAAQ;EACzB;CACF,GAAG;EAAC;EAAe;EAAmB;CAAc,CAAC;CAErD,OACE,oBAAC,sBAAD;EAAsB,GAAK,mBAAmB,EAAE,iBAAiB,IAAI,CAAC;YACpE,oBAAC,iBAAD;GAAyB;GAAS;EAA0B,CAAA;CACxC,CAAA;AAE1B"}
|
|
@@ -131,7 +131,7 @@ interface ExpoSyncoreBootstrap<TSchema extends ExpoSyncoreSchema = ExpoSyncoreSc
|
|
|
131
131
|
* Create a Syncore runtime for Expo (React Native and Expo web) backed by
|
|
132
132
|
* `expo-sqlite` on native platforms and SQL.js on web.
|
|
133
133
|
*
|
|
134
|
-
* Returns an unstarted
|
|
134
|
+
* Returns an unstarted SyncoreRuntime. Call `await runtime.start()`
|
|
135
135
|
* before using the client:
|
|
136
136
|
*
|
|
137
137
|
* ```ts
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","names":[],"sources":["../src/index.ts"],"mappings":";;;;KA6BY,iBAAA,iBACM,gBAAA,GAAmB,gBAAA,IACjC,OAAA;;AAFJ;;;;;;;;;;;;;AAEW;AAsBX;;;;;UAAiB,wBAAA,iBACC,iBAAA,GAAoB,iBAAA;EASH;EANjC,MAAA,EAAQ,OAAA;EAY2B;;;;EANnC,SAAA,EAAW,qBAAA,CAAsB,OAAA;EAmDtB;;;;EA7CX,UAAA,GAAa,qBAAA,CAAsB,OAAA;EA6DiB;;;;EAvDpD,YAAA,GAAe,mBAAA;EAlBP;;;;EAwBR,MAAA,GAAS,gBAAA;EAZI;EAeb,OAAA,GAAU,qBAAA;EATV;;;;EAeA,YAAA;EANU;;;;EAYV,iBAAA;EAkBA;;;;EAZA,oBAAA;EAqBuB;;;;EAfvB,QAAA;EAkCc;;AAAgB;AAiBhC;EA7CE,QAAA,GAAW,YAAA;EA6CwB;EA1CnC,SAAA,GAAY,gBAAA;EA2CwB;;;;EArCpC,oBAAA,GAAuB,2BAAA;EAmDf;;;;;EA5CR,qBAAA,GAAwB,4BAAA;EA8BY;;;;EAxBpC,OAAA;EAkCa;;;;EA5Bb,UAAA,IAAc,QAAA;AAAA;;AAsCE;AAuBlB;;;;;;;;;;;;UA5CiB,oBAAA,iBACC,iBAAA,GAAoB,iBAAA;EA8CF;EA3ClC,UAAA;EA4CC;;;AAAsB;EAtCvB,SAAA,IAAa,OAAA,CACX,UAAA,CAAW,cAAA,CAAe,OAAA;
|
|
1
|
+
{"version":3,"file":"index.d.ts","names":[],"sources":["../src/index.ts"],"mappings":";;;;KA6BY,iBAAA,iBACM,gBAAA,GAAmB,gBAAA,IACjC,OAAA;;AAFJ;;;;;;;;;;;;;AAEW;AAsBX;;;;;UAAiB,wBAAA,iBACC,iBAAA,GAAoB,iBAAA;EASH;EANjC,MAAA,EAAQ,OAAA;EAY2B;;;;EANnC,SAAA,EAAW,qBAAA,CAAsB,OAAA;EAmDtB;;;;EA7CX,UAAA,GAAa,qBAAA,CAAsB,OAAA;EA6DiB;;;;EAvDpD,YAAA,GAAe,mBAAA;EAlBP;;;;EAwBR,MAAA,GAAS,gBAAA;EAZI;EAeb,OAAA,GAAU,qBAAA;EATV;;;;EAeA,YAAA;EANU;;;;EAYV,iBAAA;EAkBA;;;;EAZA,oBAAA;EAqBuB;;;;EAfvB,QAAA;EAkCc;;AAAgB;AAiBhC;EA7CE,QAAA,GAAW,YAAA;EA6CwB;EA1CnC,SAAA,GAAY,gBAAA;EA2CwB;;;;EArCpC,oBAAA,GAAuB,2BAAA;EAmDf;;;;;EA5CR,qBAAA,GAAwB,4BAAA;EA8BY;;;;EAxBpC,OAAA;EAkCa;;;;EA5Bb,UAAA,IAAc,QAAA;AAAA;;AAsCE;AAuBlB;;;;;;;;;;;;UA5CiB,oBAAA,iBACC,iBAAA,GAAoB,iBAAA;EA8CF;EA3ClC,UAAA;EA4CC;;;AAAsB;EAtCvB,SAAA,IAAa,OAAA,CACX,UAAA,CAAW,cAAA,CAAe,OAAA;EAwHS;EApHrC,IAAA,IAAQ,OAAA;EAqHQ;;;;EA/GhB,KAAA,IAAS,OAAA;AAAA;;;;;;;AAgHuB;AA0BlC;;;;;;;;;;;;;iBAnHgB,wBAAA,iBACE,iBAAA,CAAA,CAEhB,OAAA,EAAS,wBAAA,CAAyB,OAAA,IACjC,cAAA,CAAe,OAAA;;;;;AAmHa;AAgD/B;;;;;;;iBAhFgB,uBAAA,iBACE,iBAAA,CAAA,CAChB,OAAA,EAAS,cAAA,CAAe,OAAA,4BAAQ,aAAA;;;;;;;;;;;;;;;;;;;;;;;iBA0BlB,0BAAA,iBACE,iBAAA,CAAA,CAEhB,OAAA,EAAS,wBAAA,CAAyB,OAAA,IACjC,oBAAA,CAAqB,OAAA;;;;cAgDX,gBAAA,YAA4B,gBAAA;EAAA,QAO7B,QAAA;EAAA,QANF,gBAAA;EAAA,QACA,MAAA;EAAA,iBACS,YAAA;EAAA,iBACA,iBAAA;cAGP,QAAA,EAAU,cAAA,EAClB,OAAA;IACE,YAAA;IACA,iBAAA;EAAA;EAOE,IAAA,CAAK,GAAA,WAAc,OAAA;EAKnB,GAAA,CACJ,GAAA,UACA,MAAA,eACC,OAAA;IAAU,OAAA;IAAiB,eAAA;EAAA;EASxB,GAAA,GAAA,CAAO,GAAA,UAAa,MAAA,eAAyB,OAAA,CAAQ,CAAA;EASrD,GAAA,GAAA,CAAO,GAAA,UAAa,MAAA,eAAyB,OAAA,CAAQ,CAAA;EAKrD,eAAA,GAAA,CAAmB,QAAA,QAAgB,OAAA,CAAQ,CAAA,IAAK,OAAA,CAAQ,CAAA;EAoBxD,aAAA,GAAA,CAAiB,IAAA,UAAc,QAAA,QAAgB,OAAA,CAAQ,CAAA,IAAK,OAAA,CAAQ,CAAA;EAkBpE,KAAA,CAAA,GAAS,OAAA;EAAA,QAQP,UAAA;EAMF,MAAA,CAAA,GAAU,OAAA;AAAA;;;;cAuCL,sBAAA,YAAkC,qBAAA;EAAA,iBAC5B,aAAA;cAEL,oBAAA;EAON,GAAA,CAAI,EAAA,UAAY,KAAA,EAAO,iBAAA,GAAoB,OAAA,CAAQ,aAAA;EAenD,GAAA,CAAI,EAAA,WAAa,OAAA,CAAQ,aAAA;EAazB,IAAA,CAAK,EAAA,WAAa,OAAA,CAAQ,UAAA;EAQ1B,MAAA,CAAO,EAAA,WAAa,OAAA;AAAA"}
|
|
@@ -7,7 +7,7 @@ import { BroadcastChannelExternalChangeSignal, createDefaultSyncChannelName, cre
|
|
|
7
7
|
* Create a Syncore runtime for Expo (React Native and Expo web) backed by
|
|
8
8
|
* `expo-sqlite` on native platforms and SQL.js on web.
|
|
9
9
|
*
|
|
10
|
-
* Returns an unstarted
|
|
10
|
+
* Returns an unstarted SyncoreRuntime. Call `await runtime.start()`
|
|
11
11
|
* before using the client:
|
|
12
12
|
*
|
|
13
13
|
* ```ts
|
|
@@ -43,6 +43,11 @@ function createExpoSyncoreRuntime(options) {
|
|
|
43
43
|
...isWebEnvironment && options.externalChangeApplier ? { externalChangeApplier: options.externalChangeApplier } : isWebEnvironment && webExternalChangeApplier ? { externalChangeApplier: webExternalChangeApplier } : {},
|
|
44
44
|
platform: options.platform ?? "expo",
|
|
45
45
|
...options.capabilities ? { capabilities: options.capabilities } : {},
|
|
46
|
+
runtimeCapabilities: { storage: {
|
|
47
|
+
available: true,
|
|
48
|
+
protocol: "file",
|
|
49
|
+
supportsRange: false
|
|
50
|
+
} },
|
|
46
51
|
...options.devtools ? { devtools: options.devtools } : {},
|
|
47
52
|
...options.scheduler ? { scheduler: options.scheduler } : {}
|
|
48
53
|
});
|