@absolutejs/sync-expo 0.0.2 → 0.0.3
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/bridge.js +7 -2
- package/dist/bridge.js.map +5 -4
- package/dist/client.js +7 -2
- package/dist/client.js.map +5 -4
- package/dist/crypto.d.ts +2 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +11 -537
- package/dist/index.js.map +6 -8
- package/package.json +4 -2
package/dist/bridge.js
CHANGED
|
@@ -1,3 +1,8 @@
|
|
|
1
|
+
// src/crypto.ts
|
|
2
|
+
import * as Crypto from "expo-crypto";
|
|
3
|
+
var expoSyncRandomBytes = (length) => Crypto.getRandomBytes(length);
|
|
4
|
+
var expoSyncRandomId = () => Crypto.randomUUID();
|
|
5
|
+
|
|
1
6
|
// src/bridge.ts
|
|
2
7
|
var requireRecord = (value, label) => {
|
|
3
8
|
if (typeof value !== "object" || value === null || Array.isArray(value))
|
|
@@ -26,7 +31,7 @@ var createExpoSyncBridgeHost = ({
|
|
|
26
31
|
store,
|
|
27
32
|
namespace,
|
|
28
33
|
transactionTimeoutMs = 8000,
|
|
29
|
-
createId =
|
|
34
|
+
createId = expoSyncRandomId
|
|
30
35
|
}) => {
|
|
31
36
|
if (!namespace || namespace.length > 512)
|
|
32
37
|
throw new TypeError("Expo Sync bridge namespace is invalid.");
|
|
@@ -348,5 +353,5 @@ export {
|
|
|
348
353
|
createExpoSyncSocketBridgeHost
|
|
349
354
|
};
|
|
350
355
|
|
|
351
|
-
//# debugId=
|
|
356
|
+
//# debugId=CE9E6EF5AE99B12064756E2164756E21
|
|
352
357
|
//# sourceMappingURL=bridge.js.map
|
package/dist/bridge.js.map
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
|
-
"sources": ["../src/bridge.ts"],
|
|
3
|
+
"sources": ["../src/crypto.ts", "../src/bridge.ts"],
|
|
4
4
|
"sourcesContent": [
|
|
5
|
-
"import type {\n LocalCollectionRecord,\n LocalMutationRecord,\n SyncLocalStore,\n SyncLocalStoreMode,\n SyncLocalTransaction,\n} from \"@absolutejs/sync/client\";\n\nexport type ExpoSyncBridgeHostOptions = {\n store: SyncLocalStore;\n namespace: string;\n /** Maximum time one WebView may hold an atomic transaction. Defaults to 8s. */\n transactionTimeoutMs?: number;\n createId?: () => string;\n};\n\nexport type ExpoSyncSocketBridgeEvent = {\n socketId: string;\n type: \"close\" | \"error\" | \"message-chunk\" | \"open\";\n code?: number;\n data?: string;\n index?: number;\n messageId?: string;\n reason?: string;\n total?: number;\n};\n\nexport type ExpoSyncSocketBridgeHostOptions = {\n allowedOrigin: string;\n socketTicket: (audience?: string) => Promise<string>;\n emit(event: ExpoSyncSocketBridgeEvent): void;\n webSocketImpl?: typeof WebSocket;\n maxSockets?: number;\n /** Maximum encoded Sync frame size. Defaults to 4 MiB. */\n maxFrameBytes?: number;\n};\n\ntype TransactionSession = {\n complete: Promise<void>;\n finish(commit: boolean): void;\n timer: ReturnType<typeof setTimeout>;\n transaction: SyncLocalTransaction;\n};\n\nconst requireRecord = (value: unknown, label: string) => {\n if (typeof value !== \"object\" || value === null || Array.isArray(value))\n throw new TypeError(`Expo Sync bridge ${label} is invalid.`);\n\n return value as Record<string, unknown>;\n};\n\nconst requireString = (value: unknown, label: string) => {\n if (typeof value !== \"string\" || value.length === 0 || value.length > 512)\n throw new TypeError(`Expo Sync bridge ${label} is invalid.`);\n\n return value;\n};\n\nconst requireCollectionRecord = (value: unknown): LocalCollectionRecord => {\n const record = requireRecord(value, \"collection record\");\n if (\n !Array.isArray(record.rows) ||\n typeof record.version !== \"number\" ||\n !Number.isSafeInteger(record.version) ||\n record.version < 0\n )\n throw new TypeError(\"Expo Sync bridge collection record is invalid.\");\n\n return structuredClone(record) as LocalCollectionRecord;\n};\n\nconst requireMutationRecord = (value: unknown): LocalMutationRecord => {\n const record = requireRecord(value, \"mutation record\");\n if (\n typeof record.operationId !== \"string\" ||\n record.operationId.length === 0 ||\n record.operationId.length > 512 ||\n typeof record.name !== \"string\" ||\n record.name.length === 0 ||\n record.name.length > 512 ||\n typeof record.createdAt !== \"number\" ||\n !Number.isFinite(record.createdAt) ||\n typeof record.attempts !== \"number\" ||\n !Number.isSafeInteger(record.attempts) ||\n record.attempts < 0 ||\n !Array.isArray(record.optimistic) ||\n !Array.isArray(record.inverse)\n )\n throw new TypeError(\"Expo Sync bridge mutation record is invalid.\");\n\n return structuredClone(record) as LocalMutationRecord;\n};\n\nconst rollbackMarker = Symbol(\"expo-sync-bridge-rollback\");\n\n/**\n * Native owner for WebView local-store transactions. It exposes only Sync's\n * typed persistence contract and never accepts a namespace from page code.\n */\nexport const createExpoSyncBridgeHost = ({\n store,\n namespace,\n transactionTimeoutMs = 8_000,\n createId = () => crypto.randomUUID(),\n}: ExpoSyncBridgeHostOptions) => {\n if (!namespace || namespace.length > 512)\n throw new TypeError(\"Expo Sync bridge namespace is invalid.\");\n if (\n !Number.isSafeInteger(transactionTimeoutMs) ||\n transactionTimeoutMs < 100 ||\n transactionTimeoutMs > 30_000\n )\n throw new TypeError(\n \"Expo Sync bridge transactionTimeoutMs must be between 100 and 30000.\",\n );\n const sessions = new Map<string, TransactionSession>();\n\n const begin = async (mode: SyncLocalStoreMode) => {\n if (sessions.size >= 8)\n throw new Error(\"Expo Sync bridge has too many open transactions.\");\n const id = createId();\n if (!/^[A-Za-z0-9._:-]{1,160}$/u.test(id) || sessions.has(id))\n throw new Error(\"Expo Sync bridge generated an invalid transaction id.\");\n let readyResolve: (transaction: SyncLocalTransaction) => void = () =>\n undefined;\n let readyReject: (error: unknown) => void = () => undefined;\n const ready = new Promise<SyncLocalTransaction>((resolve, reject) => {\n readyResolve = resolve;\n readyReject = reject;\n });\n let finish: (commit: boolean) => void = () => undefined;\n const decision = new Promise<boolean>((resolve) => {\n finish = resolve;\n });\n const complete = store\n .transaction(namespace, mode, async (transaction) => {\n readyResolve(transaction);\n if (!(await decision)) throw rollbackMarker;\n })\n .catch((error) => {\n readyReject(error);\n if (error !== rollbackMarker) throw error;\n });\n const transaction = await ready;\n const timer = setTimeout(() => {\n sessions.delete(id);\n finish(false);\n }, transactionTimeoutMs);\n sessions.set(id, { complete, finish, timer, transaction });\n\n return id;\n };\n\n const session = (params: Record<string, unknown>) => {\n const id = requireString(params.transactionId, \"transaction id\");\n const value = sessions.get(id);\n if (!value)\n throw new Error(\"Expo Sync bridge transaction is closed or unknown.\");\n\n return { id, value };\n };\n\n const end = async (params: Record<string, unknown>) => {\n const { id, value } = session(params);\n if (typeof params.commit !== \"boolean\")\n throw new TypeError(\"Expo Sync bridge commit decision is invalid.\");\n sessions.delete(id);\n clearTimeout(value.timer);\n value.finish(params.commit);\n await value.complete;\n\n return null;\n };\n\n const operation = async (\n method: string,\n params: Record<string, unknown>,\n ): Promise<unknown> => {\n const { value } = session(params);\n const transaction = value.transaction;\n if (method === \"sync.tx.getInstallationId\")\n return (await transaction.getInstallationId()) ?? null;\n if (method === \"sync.tx.setInstallationId\") {\n await transaction.setInstallationId(\n requireString(params.installationId, \"installation id\"),\n );\n\n return null;\n }\n if (method === \"sync.tx.getCollection\")\n return (\n (await transaction.getCollection(\n requireString(params.key, \"collection key\"),\n )) ?? null\n );\n if (method === \"sync.tx.listCollections\")\n return transaction.listCollections();\n if (method === \"sync.tx.putCollection\") {\n await transaction.putCollection(\n requireString(params.key, \"collection key\"),\n requireCollectionRecord(params.record),\n );\n\n return null;\n }\n if (method === \"sync.tx.deleteCollection\") {\n await transaction.deleteCollection(\n requireString(params.key, \"collection key\"),\n );\n\n return null;\n }\n if (method === \"sync.tx.listMutations\") return transaction.listMutations();\n if (method === \"sync.tx.getMutation\")\n return (\n (await transaction.getMutation(\n requireString(params.operationId, \"operation id\"),\n )) ?? null\n );\n if (method === \"sync.tx.putMutation\") {\n await transaction.putMutation(requireMutationRecord(params.record));\n\n return null;\n }\n if (method === \"sync.tx.deleteMutation\") {\n await transaction.deleteMutation(\n requireString(params.operationId, \"operation id\"),\n );\n\n return null;\n }\n if (method === \"sync.tx.resolveMutationPolicy\")\n return (\n transaction.resolveMutationPolicy?.(\n requireString(params.name, \"mutation name\"),\n ) ?? null\n );\n throw new Error(\"Expo Sync bridge transaction method is not allowed.\");\n };\n\n return {\n close: async () => {\n const active = [...sessions.values()];\n sessions.clear();\n for (const value of active) {\n clearTimeout(value.timer);\n value.finish(false);\n }\n await Promise.allSettled(active.map((value) => value.complete));\n },\n request: async (method: string, rawParams: unknown): Promise<unknown> => {\n const params = requireRecord(rawParams, \"params\");\n if (method === \"sync.store.begin\") {\n if (params.mode !== \"readonly\" && params.mode !== \"readwrite\")\n throw new TypeError(\"Expo Sync bridge transaction mode is invalid.\");\n\n return { transactionId: await begin(params.mode) };\n }\n if (method === \"sync.store.end\") return end(params);\n if (method === \"sync.store.schema\")\n return (await store.getSchemaStatus?.()) ?? null;\n if (method === \"sync.store.deleteNamespace\") {\n await store.deleteNamespace?.(namespace);\n\n return null;\n }\n if (method.startsWith(\"sync.tx.\")) return operation(method, params);\n throw new Error(\"Expo Sync bridge method is not allowed.\");\n },\n };\n};\n\nconst websocketOrigin = (url: URL) => {\n const protocol = url.protocol === \"wss:\" ? \"https:\" : \"http:\";\n\n return `${protocol}//${url.host}`;\n};\n\nconst ticketSocketUrl = (url: URL) => {\n if (url.searchParams.has(\"__absolute_auth\"))\n throw new TypeError(\n \"Expo Sync socket URL contains reserved authentication.\",\n );\n url.searchParams.set(\"__absolute_auth\", \"ticket\");\n\n return url.href;\n};\n\nconst SOCKET_CHUNK_BYTES = 24 * 1024;\nconst SOCKET_UPLOAD_TIMEOUT_MS = 10_000;\nconst encodeBase64 = (value: Uint8Array) => {\n let binary = \"\";\n for (const byte of value) binary += String.fromCharCode(byte);\n\n return btoa(binary);\n};\nconst decodeBase64 = (value: string) => {\n if (\n value.length === 0 ||\n value.length > Math.ceil(SOCKET_CHUNK_BYTES / 3) * 4 + 4 ||\n !/^[A-Za-z0-9+/]+={0,2}$/u.test(value)\n )\n throw new TypeError(\"Expo Sync socket chunk is invalid.\");\n\n return Uint8Array.from(atob(value), (character) => character.charCodeAt(0));\n};\n\n/**\n * Owns authenticated sockets in native JavaScript. Only ordinary string Sync\n * frames cross the WebView bridge; the single-use ticket is consumed here.\n */\nexport const createExpoSyncSocketBridgeHost = ({\n allowedOrigin,\n socketTicket,\n emit,\n webSocketImpl = globalThis.WebSocket,\n maxSockets = 4,\n maxFrameBytes = 4 * 1024 * 1024,\n}: ExpoSyncSocketBridgeHostOptions) => {\n const origin = new URL(allowedOrigin);\n if (\n origin.protocol !== \"https:\" ||\n origin.username ||\n origin.password ||\n origin.pathname !== \"/\" ||\n origin.search ||\n origin.hash\n )\n throw new TypeError(\n \"Expo Sync socket allowedOrigin must be an HTTPS origin.\",\n );\n if (!webSocketImpl)\n throw new Error(\"Expo Sync socket bridge requires WebSocket support.\");\n if (!Number.isSafeInteger(maxSockets) || maxSockets < 1 || maxSockets > 16)\n throw new TypeError(\"Expo Sync maxSockets must be between 1 and 16.\");\n if (\n !Number.isSafeInteger(maxFrameBytes) ||\n maxFrameBytes < SOCKET_CHUNK_BYTES ||\n maxFrameBytes > 16 * 1024 * 1024\n )\n throw new TypeError(\n \"Expo Sync maxFrameBytes must be between 24 KiB and 16 MiB.\",\n );\n const sockets = new Map<string, WebSocket>();\n const uploads = new Map<\n string,\n {\n chunks: Array<Uint8Array | undefined>;\n timer: ReturnType<typeof setTimeout>;\n }\n >();\n let messageSequence = 0;\n const socketId = (value: unknown) => {\n const id = requireString(value, \"socket id\");\n if (!/^[A-Za-z0-9._:-]{1,160}$/u.test(id))\n throw new TypeError(\"Expo Sync bridge socket id is invalid.\");\n\n return id;\n };\n const close = (id: string, code?: number, reason?: string) => {\n const socket = sockets.get(id);\n if (!socket) return;\n sockets.delete(id);\n for (const [key, upload] of uploads)\n if (key.startsWith(`${id}:\\u0000`)) {\n clearTimeout(upload.timer);\n uploads.delete(key);\n }\n socket.close(code, reason);\n };\n const emitMessage = (id: string, data: string) => {\n const bytes = new TextEncoder().encode(data);\n if (bytes.byteLength > maxFrameBytes) {\n emit({ socketId: id, type: \"error\" });\n close(id, 1009, \"Sync frame is too large\");\n\n return;\n }\n const total = Math.max(1, Math.ceil(bytes.byteLength / SOCKET_CHUNK_BYTES));\n const messageId = `native_${(messageSequence += 1).toString(36)}`;\n for (let index = 0; index < total; index += 1)\n emit({\n data: encodeBase64(\n bytes.slice(\n index * SOCKET_CHUNK_BYTES,\n Math.min(bytes.byteLength, (index + 1) * SOCKET_CHUNK_BYTES),\n ),\n ),\n index,\n messageId,\n socketId: id,\n total,\n type: \"message-chunk\",\n });\n };\n\n return {\n close: () => {\n for (const id of [...sockets.keys()]) close(id, 1000, \"Host closed\");\n },\n request: async (method: string, rawParams: unknown): Promise<unknown> => {\n const params = requireRecord(rawParams, \"socket params\");\n const id = socketId(params.socketId);\n if (method === \"sync.socket.open\") {\n if (sockets.has(id))\n throw new Error(\"Expo Sync bridge socket id is already open.\");\n if (sockets.size >= maxSockets)\n throw new Error(\"Expo Sync bridge socket limit exceeded.\");\n const url = new URL(requireString(params.url, \"socket URL\"));\n if (\n url.protocol !== \"wss:\" ||\n url.username ||\n url.password ||\n websocketOrigin(url) !== origin.origin\n )\n throw new Error(\n \"Expo Sync socket must use WSS on the configured production origin.\",\n );\n const socket = new webSocketImpl(ticketSocketUrl(url));\n sockets.set(id, socket);\n socket.onopen = () => {\n void socketTicket(origin.origin)\n .then((ticket) => {\n if (sockets.get(id) !== socket) return;\n socket.send(JSON.stringify({ ticket, type: \"authenticate\" }));\n emit({ socketId: id, type: \"open\" });\n })\n .catch(() => {\n if (sockets.get(id) !== socket) return;\n emit({ socketId: id, type: \"error\" });\n close(id, 1008, \"Authentication failed\");\n });\n };\n socket.onmessage = (event) => {\n if (sockets.get(id) !== socket) return;\n if (typeof event.data !== \"string\") {\n emit({ socketId: id, type: \"error\" });\n close(id, 1003, \"Binary frames are not supported\");\n\n return;\n }\n emitMessage(id, event.data);\n };\n socket.onerror = () => {\n if (sockets.get(id) === socket) emit({ socketId: id, type: \"error\" });\n };\n socket.onclose = (event) => {\n if (sockets.get(id) === socket) sockets.delete(id);\n emit({\n code: event.code,\n reason: event.reason,\n socketId: id,\n type: \"close\",\n });\n };\n\n return null;\n }\n if (method === \"sync.socket.sendChunk\") {\n const socket = sockets.get(id);\n if (!socket || socket.readyState !== webSocketImpl.OPEN)\n throw new Error(\"Expo Sync bridge socket is not open.\");\n const messageId = requireString(params.messageId, \"message id\");\n const index = params.index;\n const total = params.total;\n if (\n typeof index !== \"number\" ||\n !Number.isSafeInteger(index) ||\n typeof total !== \"number\" ||\n !Number.isSafeInteger(total) ||\n index < 0 ||\n total < 1 ||\n index >= total ||\n total > Math.ceil(maxFrameBytes / SOCKET_CHUNK_BYTES)\n )\n throw new TypeError(\"Expo Sync socket chunk position is invalid.\");\n if (typeof params.data !== \"string\")\n throw new TypeError(\"Expo Sync socket chunk data is invalid.\");\n const key = `${id}:\\u0000${messageId}`;\n let upload = uploads.get(key);\n if (!upload) {\n const timer = setTimeout(\n () => uploads.delete(key),\n SOCKET_UPLOAD_TIMEOUT_MS,\n );\n upload = { chunks: Array.from({ length: total }), timer };\n uploads.set(key, upload);\n }\n if (upload.chunks.length !== total || upload.chunks[index])\n throw new Error(\"Expo Sync socket chunk sequence is invalid.\");\n upload.chunks[index] = decodeBase64(params.data);\n if (upload.chunks.every((chunk) => chunk !== undefined)) {\n clearTimeout(upload.timer);\n uploads.delete(key);\n const size = upload.chunks.reduce(\n (sum, chunk) => sum + (chunk?.byteLength ?? 0),\n 0,\n );\n if (size > maxFrameBytes)\n throw new Error(\"Expo Sync socket frame exceeds its byte limit.\");\n const bytes = new Uint8Array(size);\n let offset = 0;\n for (const chunk of upload.chunks) {\n bytes.set(chunk!, offset);\n offset += chunk!.byteLength;\n }\n socket.send(new TextDecoder().decode(bytes));\n }\n\n return null;\n }\n if (method === \"sync.socket.close\") {\n const code =\n params.code === undefined\n ? undefined\n : typeof params.code === \"number\" &&\n Number.isSafeInteger(params.code) &&\n params.code >= 1000 &&\n params.code <= 4999\n ? params.code\n : null;\n if (code === null)\n throw new TypeError(\"Expo Sync bridge close code is invalid.\");\n const reason =\n params.reason === undefined\n ? undefined\n : requireString(params.reason, \"close reason\");\n close(id, code, reason);\n\n return null;\n }\n throw new Error(\"Expo Sync socket bridge method is not allowed.\");\n },\n };\n};\n"
|
|
5
|
+
"import * as Crypto from \"expo-crypto\";\n\nexport const expoSyncRandomBytes = (length: number) =>\n Crypto.getRandomBytes(length);\n\nexport const expoSyncRandomId = () => Crypto.randomUUID();\n",
|
|
6
|
+
"import type {\n LocalCollectionRecord,\n LocalMutationRecord,\n SyncLocalStore,\n SyncLocalStoreMode,\n SyncLocalTransaction,\n} from \"@absolutejs/sync/client\";\nimport { expoSyncRandomId } from \"./crypto\";\n\nexport type ExpoSyncBridgeHostOptions = {\n store: SyncLocalStore;\n namespace: string;\n /** Maximum time one WebView may hold an atomic transaction. Defaults to 8s. */\n transactionTimeoutMs?: number;\n createId?: () => string;\n};\n\nexport type ExpoSyncSocketBridgeEvent = {\n socketId: string;\n type: \"close\" | \"error\" | \"message-chunk\" | \"open\";\n code?: number;\n data?: string;\n index?: number;\n messageId?: string;\n reason?: string;\n total?: number;\n};\n\nexport type ExpoSyncSocketBridgeHostOptions = {\n allowedOrigin: string;\n socketTicket: (audience?: string) => Promise<string>;\n emit(event: ExpoSyncSocketBridgeEvent): void;\n webSocketImpl?: typeof WebSocket;\n maxSockets?: number;\n /** Maximum encoded Sync frame size. Defaults to 4 MiB. */\n maxFrameBytes?: number;\n};\n\ntype TransactionSession = {\n complete: Promise<void>;\n finish(commit: boolean): void;\n timer: ReturnType<typeof setTimeout>;\n transaction: SyncLocalTransaction;\n};\n\nconst requireRecord = (value: unknown, label: string) => {\n if (typeof value !== \"object\" || value === null || Array.isArray(value))\n throw new TypeError(`Expo Sync bridge ${label} is invalid.`);\n\n return value as Record<string, unknown>;\n};\n\nconst requireString = (value: unknown, label: string) => {\n if (typeof value !== \"string\" || value.length === 0 || value.length > 512)\n throw new TypeError(`Expo Sync bridge ${label} is invalid.`);\n\n return value;\n};\n\nconst requireCollectionRecord = (value: unknown): LocalCollectionRecord => {\n const record = requireRecord(value, \"collection record\");\n if (\n !Array.isArray(record.rows) ||\n typeof record.version !== \"number\" ||\n !Number.isSafeInteger(record.version) ||\n record.version < 0\n )\n throw new TypeError(\"Expo Sync bridge collection record is invalid.\");\n\n return structuredClone(record) as LocalCollectionRecord;\n};\n\nconst requireMutationRecord = (value: unknown): LocalMutationRecord => {\n const record = requireRecord(value, \"mutation record\");\n if (\n typeof record.operationId !== \"string\" ||\n record.operationId.length === 0 ||\n record.operationId.length > 512 ||\n typeof record.name !== \"string\" ||\n record.name.length === 0 ||\n record.name.length > 512 ||\n typeof record.createdAt !== \"number\" ||\n !Number.isFinite(record.createdAt) ||\n typeof record.attempts !== \"number\" ||\n !Number.isSafeInteger(record.attempts) ||\n record.attempts < 0 ||\n !Array.isArray(record.optimistic) ||\n !Array.isArray(record.inverse)\n )\n throw new TypeError(\"Expo Sync bridge mutation record is invalid.\");\n\n return structuredClone(record) as LocalMutationRecord;\n};\n\nconst rollbackMarker = Symbol(\"expo-sync-bridge-rollback\");\n\n/**\n * Native owner for WebView local-store transactions. It exposes only Sync's\n * typed persistence contract and never accepts a namespace from page code.\n */\nexport const createExpoSyncBridgeHost = ({\n store,\n namespace,\n transactionTimeoutMs = 8_000,\n createId = expoSyncRandomId,\n}: ExpoSyncBridgeHostOptions) => {\n if (!namespace || namespace.length > 512)\n throw new TypeError(\"Expo Sync bridge namespace is invalid.\");\n if (\n !Number.isSafeInteger(transactionTimeoutMs) ||\n transactionTimeoutMs < 100 ||\n transactionTimeoutMs > 30_000\n )\n throw new TypeError(\n \"Expo Sync bridge transactionTimeoutMs must be between 100 and 30000.\",\n );\n const sessions = new Map<string, TransactionSession>();\n\n const begin = async (mode: SyncLocalStoreMode) => {\n if (sessions.size >= 8)\n throw new Error(\"Expo Sync bridge has too many open transactions.\");\n const id = createId();\n if (!/^[A-Za-z0-9._:-]{1,160}$/u.test(id) || sessions.has(id))\n throw new Error(\"Expo Sync bridge generated an invalid transaction id.\");\n let readyResolve: (transaction: SyncLocalTransaction) => void = () =>\n undefined;\n let readyReject: (error: unknown) => void = () => undefined;\n const ready = new Promise<SyncLocalTransaction>((resolve, reject) => {\n readyResolve = resolve;\n readyReject = reject;\n });\n let finish: (commit: boolean) => void = () => undefined;\n const decision = new Promise<boolean>((resolve) => {\n finish = resolve;\n });\n const complete = store\n .transaction(namespace, mode, async (transaction) => {\n readyResolve(transaction);\n if (!(await decision)) throw rollbackMarker;\n })\n .catch((error) => {\n readyReject(error);\n if (error !== rollbackMarker) throw error;\n });\n const transaction = await ready;\n const timer = setTimeout(() => {\n sessions.delete(id);\n finish(false);\n }, transactionTimeoutMs);\n sessions.set(id, { complete, finish, timer, transaction });\n\n return id;\n };\n\n const session = (params: Record<string, unknown>) => {\n const id = requireString(params.transactionId, \"transaction id\");\n const value = sessions.get(id);\n if (!value)\n throw new Error(\"Expo Sync bridge transaction is closed or unknown.\");\n\n return { id, value };\n };\n\n const end = async (params: Record<string, unknown>) => {\n const { id, value } = session(params);\n if (typeof params.commit !== \"boolean\")\n throw new TypeError(\"Expo Sync bridge commit decision is invalid.\");\n sessions.delete(id);\n clearTimeout(value.timer);\n value.finish(params.commit);\n await value.complete;\n\n return null;\n };\n\n const operation = async (\n method: string,\n params: Record<string, unknown>,\n ): Promise<unknown> => {\n const { value } = session(params);\n const transaction = value.transaction;\n if (method === \"sync.tx.getInstallationId\")\n return (await transaction.getInstallationId()) ?? null;\n if (method === \"sync.tx.setInstallationId\") {\n await transaction.setInstallationId(\n requireString(params.installationId, \"installation id\"),\n );\n\n return null;\n }\n if (method === \"sync.tx.getCollection\")\n return (\n (await transaction.getCollection(\n requireString(params.key, \"collection key\"),\n )) ?? null\n );\n if (method === \"sync.tx.listCollections\")\n return transaction.listCollections();\n if (method === \"sync.tx.putCollection\") {\n await transaction.putCollection(\n requireString(params.key, \"collection key\"),\n requireCollectionRecord(params.record),\n );\n\n return null;\n }\n if (method === \"sync.tx.deleteCollection\") {\n await transaction.deleteCollection(\n requireString(params.key, \"collection key\"),\n );\n\n return null;\n }\n if (method === \"sync.tx.listMutations\") return transaction.listMutations();\n if (method === \"sync.tx.getMutation\")\n return (\n (await transaction.getMutation(\n requireString(params.operationId, \"operation id\"),\n )) ?? null\n );\n if (method === \"sync.tx.putMutation\") {\n await transaction.putMutation(requireMutationRecord(params.record));\n\n return null;\n }\n if (method === \"sync.tx.deleteMutation\") {\n await transaction.deleteMutation(\n requireString(params.operationId, \"operation id\"),\n );\n\n return null;\n }\n if (method === \"sync.tx.resolveMutationPolicy\")\n return (\n transaction.resolveMutationPolicy?.(\n requireString(params.name, \"mutation name\"),\n ) ?? null\n );\n throw new Error(\"Expo Sync bridge transaction method is not allowed.\");\n };\n\n return {\n close: async () => {\n const active = [...sessions.values()];\n sessions.clear();\n for (const value of active) {\n clearTimeout(value.timer);\n value.finish(false);\n }\n await Promise.allSettled(active.map((value) => value.complete));\n },\n request: async (method: string, rawParams: unknown): Promise<unknown> => {\n const params = requireRecord(rawParams, \"params\");\n if (method === \"sync.store.begin\") {\n if (params.mode !== \"readonly\" && params.mode !== \"readwrite\")\n throw new TypeError(\"Expo Sync bridge transaction mode is invalid.\");\n\n return { transactionId: await begin(params.mode) };\n }\n if (method === \"sync.store.end\") return end(params);\n if (method === \"sync.store.schema\")\n return (await store.getSchemaStatus?.()) ?? null;\n if (method === \"sync.store.deleteNamespace\") {\n await store.deleteNamespace?.(namespace);\n\n return null;\n }\n if (method.startsWith(\"sync.tx.\")) return operation(method, params);\n throw new Error(\"Expo Sync bridge method is not allowed.\");\n },\n };\n};\n\nconst websocketOrigin = (url: URL) => {\n const protocol = url.protocol === \"wss:\" ? \"https:\" : \"http:\";\n\n return `${protocol}//${url.host}`;\n};\n\nconst ticketSocketUrl = (url: URL) => {\n if (url.searchParams.has(\"__absolute_auth\"))\n throw new TypeError(\n \"Expo Sync socket URL contains reserved authentication.\",\n );\n url.searchParams.set(\"__absolute_auth\", \"ticket\");\n\n return url.href;\n};\n\nconst SOCKET_CHUNK_BYTES = 24 * 1024;\nconst SOCKET_UPLOAD_TIMEOUT_MS = 10_000;\nconst encodeBase64 = (value: Uint8Array) => {\n let binary = \"\";\n for (const byte of value) binary += String.fromCharCode(byte);\n\n return btoa(binary);\n};\nconst decodeBase64 = (value: string) => {\n if (\n value.length === 0 ||\n value.length > Math.ceil(SOCKET_CHUNK_BYTES / 3) * 4 + 4 ||\n !/^[A-Za-z0-9+/]+={0,2}$/u.test(value)\n )\n throw new TypeError(\"Expo Sync socket chunk is invalid.\");\n\n return Uint8Array.from(atob(value), (character) => character.charCodeAt(0));\n};\n\n/**\n * Owns authenticated sockets in native JavaScript. Only ordinary string Sync\n * frames cross the WebView bridge; the single-use ticket is consumed here.\n */\nexport const createExpoSyncSocketBridgeHost = ({\n allowedOrigin,\n socketTicket,\n emit,\n webSocketImpl = globalThis.WebSocket,\n maxSockets = 4,\n maxFrameBytes = 4 * 1024 * 1024,\n}: ExpoSyncSocketBridgeHostOptions) => {\n const origin = new URL(allowedOrigin);\n if (\n origin.protocol !== \"https:\" ||\n origin.username ||\n origin.password ||\n origin.pathname !== \"/\" ||\n origin.search ||\n origin.hash\n )\n throw new TypeError(\n \"Expo Sync socket allowedOrigin must be an HTTPS origin.\",\n );\n if (!webSocketImpl)\n throw new Error(\"Expo Sync socket bridge requires WebSocket support.\");\n if (!Number.isSafeInteger(maxSockets) || maxSockets < 1 || maxSockets > 16)\n throw new TypeError(\"Expo Sync maxSockets must be between 1 and 16.\");\n if (\n !Number.isSafeInteger(maxFrameBytes) ||\n maxFrameBytes < SOCKET_CHUNK_BYTES ||\n maxFrameBytes > 16 * 1024 * 1024\n )\n throw new TypeError(\n \"Expo Sync maxFrameBytes must be between 24 KiB and 16 MiB.\",\n );\n const sockets = new Map<string, WebSocket>();\n const uploads = new Map<\n string,\n {\n chunks: Array<Uint8Array | undefined>;\n timer: ReturnType<typeof setTimeout>;\n }\n >();\n let messageSequence = 0;\n const socketId = (value: unknown) => {\n const id = requireString(value, \"socket id\");\n if (!/^[A-Za-z0-9._:-]{1,160}$/u.test(id))\n throw new TypeError(\"Expo Sync bridge socket id is invalid.\");\n\n return id;\n };\n const close = (id: string, code?: number, reason?: string) => {\n const socket = sockets.get(id);\n if (!socket) return;\n sockets.delete(id);\n for (const [key, upload] of uploads)\n if (key.startsWith(`${id}:\\u0000`)) {\n clearTimeout(upload.timer);\n uploads.delete(key);\n }\n socket.close(code, reason);\n };\n const emitMessage = (id: string, data: string) => {\n const bytes = new TextEncoder().encode(data);\n if (bytes.byteLength > maxFrameBytes) {\n emit({ socketId: id, type: \"error\" });\n close(id, 1009, \"Sync frame is too large\");\n\n return;\n }\n const total = Math.max(1, Math.ceil(bytes.byteLength / SOCKET_CHUNK_BYTES));\n const messageId = `native_${(messageSequence += 1).toString(36)}`;\n for (let index = 0; index < total; index += 1)\n emit({\n data: encodeBase64(\n bytes.slice(\n index * SOCKET_CHUNK_BYTES,\n Math.min(bytes.byteLength, (index + 1) * SOCKET_CHUNK_BYTES),\n ),\n ),\n index,\n messageId,\n socketId: id,\n total,\n type: \"message-chunk\",\n });\n };\n\n return {\n close: () => {\n for (const id of [...sockets.keys()]) close(id, 1000, \"Host closed\");\n },\n request: async (method: string, rawParams: unknown): Promise<unknown> => {\n const params = requireRecord(rawParams, \"socket params\");\n const id = socketId(params.socketId);\n if (method === \"sync.socket.open\") {\n if (sockets.has(id))\n throw new Error(\"Expo Sync bridge socket id is already open.\");\n if (sockets.size >= maxSockets)\n throw new Error(\"Expo Sync bridge socket limit exceeded.\");\n const url = new URL(requireString(params.url, \"socket URL\"));\n if (\n url.protocol !== \"wss:\" ||\n url.username ||\n url.password ||\n websocketOrigin(url) !== origin.origin\n )\n throw new Error(\n \"Expo Sync socket must use WSS on the configured production origin.\",\n );\n const socket = new webSocketImpl(ticketSocketUrl(url));\n sockets.set(id, socket);\n socket.onopen = () => {\n void socketTicket(origin.origin)\n .then((ticket) => {\n if (sockets.get(id) !== socket) return;\n socket.send(JSON.stringify({ ticket, type: \"authenticate\" }));\n emit({ socketId: id, type: \"open\" });\n })\n .catch(() => {\n if (sockets.get(id) !== socket) return;\n emit({ socketId: id, type: \"error\" });\n close(id, 1008, \"Authentication failed\");\n });\n };\n socket.onmessage = (event) => {\n if (sockets.get(id) !== socket) return;\n if (typeof event.data !== \"string\") {\n emit({ socketId: id, type: \"error\" });\n close(id, 1003, \"Binary frames are not supported\");\n\n return;\n }\n emitMessage(id, event.data);\n };\n socket.onerror = () => {\n if (sockets.get(id) === socket) emit({ socketId: id, type: \"error\" });\n };\n socket.onclose = (event) => {\n if (sockets.get(id) === socket) sockets.delete(id);\n emit({\n code: event.code,\n reason: event.reason,\n socketId: id,\n type: \"close\",\n });\n };\n\n return null;\n }\n if (method === \"sync.socket.sendChunk\") {\n const socket = sockets.get(id);\n if (!socket || socket.readyState !== webSocketImpl.OPEN)\n throw new Error(\"Expo Sync bridge socket is not open.\");\n const messageId = requireString(params.messageId, \"message id\");\n const index = params.index;\n const total = params.total;\n if (\n typeof index !== \"number\" ||\n !Number.isSafeInteger(index) ||\n typeof total !== \"number\" ||\n !Number.isSafeInteger(total) ||\n index < 0 ||\n total < 1 ||\n index >= total ||\n total > Math.ceil(maxFrameBytes / SOCKET_CHUNK_BYTES)\n )\n throw new TypeError(\"Expo Sync socket chunk position is invalid.\");\n if (typeof params.data !== \"string\")\n throw new TypeError(\"Expo Sync socket chunk data is invalid.\");\n const key = `${id}:\\u0000${messageId}`;\n let upload = uploads.get(key);\n if (!upload) {\n const timer = setTimeout(\n () => uploads.delete(key),\n SOCKET_UPLOAD_TIMEOUT_MS,\n );\n upload = { chunks: Array.from({ length: total }), timer };\n uploads.set(key, upload);\n }\n if (upload.chunks.length !== total || upload.chunks[index])\n throw new Error(\"Expo Sync socket chunk sequence is invalid.\");\n upload.chunks[index] = decodeBase64(params.data);\n if (upload.chunks.every((chunk) => chunk !== undefined)) {\n clearTimeout(upload.timer);\n uploads.delete(key);\n const size = upload.chunks.reduce(\n (sum, chunk) => sum + (chunk?.byteLength ?? 0),\n 0,\n );\n if (size > maxFrameBytes)\n throw new Error(\"Expo Sync socket frame exceeds its byte limit.\");\n const bytes = new Uint8Array(size);\n let offset = 0;\n for (const chunk of upload.chunks) {\n bytes.set(chunk!, offset);\n offset += chunk!.byteLength;\n }\n socket.send(new TextDecoder().decode(bytes));\n }\n\n return null;\n }\n if (method === \"sync.socket.close\") {\n const code =\n params.code === undefined\n ? undefined\n : typeof params.code === \"number\" &&\n Number.isSafeInteger(params.code) &&\n params.code >= 1000 &&\n params.code <= 4999\n ? params.code\n : null;\n if (code === null)\n throw new TypeError(\"Expo Sync bridge close code is invalid.\");\n const reason =\n params.reason === undefined\n ? undefined\n : requireString(params.reason, \"close reason\");\n close(id, code, reason);\n\n return null;\n }\n throw new Error(\"Expo Sync socket bridge method is not allowed.\");\n },\n };\n};\n"
|
|
6
7
|
],
|
|
7
|
-
"mappings": "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",
|
|
8
|
-
"debugId": "
|
|
8
|
+
"mappings": "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",
|
|
9
|
+
"debugId": "CE9E6EF5AE99B12064756E2164756E21",
|
|
9
10
|
"names": []
|
|
10
11
|
}
|
package/dist/client.js
CHANGED
|
@@ -1,3 +1,8 @@
|
|
|
1
|
+
// src/crypto.ts
|
|
2
|
+
import * as Crypto from "expo-crypto";
|
|
3
|
+
var expoSyncRandomBytes = (length) => Crypto.getRandomBytes(length);
|
|
4
|
+
var expoSyncRandomId = () => Crypto.randomUUID();
|
|
5
|
+
|
|
1
6
|
// src/client.ts
|
|
2
7
|
import {
|
|
3
8
|
resolveSyncLocalDataPolicy,
|
|
@@ -106,7 +111,7 @@ var createExpoSyncBridgeWebSocket = (provider) => {
|
|
|
106
111
|
protocol = "";
|
|
107
112
|
readyState = ExpoBridgeWebSocket.CONNECTING;
|
|
108
113
|
url;
|
|
109
|
-
#socketId = `websocket_${
|
|
114
|
+
#socketId = `websocket_${expoSyncRandomId()}`;
|
|
110
115
|
#messages = new Map;
|
|
111
116
|
#remove;
|
|
112
117
|
#sendSequence = 0;
|
|
@@ -251,5 +256,5 @@ export {
|
|
|
251
256
|
createExpoSyncBridgeWebSocket
|
|
252
257
|
};
|
|
253
258
|
|
|
254
|
-
//# debugId=
|
|
259
|
+
//# debugId=456B48D3DEE2D99264756E2164756E21
|
|
255
260
|
//# sourceMappingURL=client.js.map
|
package/dist/client.js.map
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
|
-
"sources": ["../src/client.ts"],
|
|
3
|
+
"sources": ["../src/crypto.ts", "../src/client.ts"],
|
|
4
4
|
"sourcesContent": [
|
|
5
|
-
"import type {\n LocalCollectionRecord,\n LocalMutationRecord,\n SyncLocalStore,\n SyncLocalStoreMode,\n SyncLocalStoreSchemaInput,\n SyncLocalStoreSchemaStatus,\n SyncLocalTransaction,\n} from \"@absolutejs/sync/client\";\nimport {\n resolveSyncLocalDataPolicy,\n resolveSyncLocalMutationPolicy,\n} from \"@absolutejs/sync/client\";\n\nexport type AbsoluteExpoSyncBridgeProvider = {\n on(\n event: \"sync.socket\",\n listener: (payload: Record<string, unknown>) => void,\n ): () => void;\n request(method: string, params: Record<string, unknown>): Promise<unknown>;\n};\n\nexport type ExpoSyncBridgeLocalStoreOptions = {\n provider: AbsoluteExpoSyncBridgeProvider;\n storageSchema?: SyncLocalStoreSchemaInput;\n};\n\nconst record = (value: unknown, label: string) => {\n if (typeof value !== \"object\" || value === null || Array.isArray(value))\n throw new TypeError(`Expo Sync bridge returned invalid ${label}.`);\n\n return value as Record<string, unknown>;\n};\n\nconst transactionId = (value: unknown) => {\n const id = Reflect.get(record(value, \"transaction\"), \"transactionId\");\n if (typeof id !== \"string\" || id.length === 0)\n throw new TypeError(\"Expo Sync bridge returned an invalid transaction id.\");\n\n return id;\n};\n\nconst nullable = <T>(value: unknown): T | undefined =>\n value === null || value === undefined ? undefined : (value as T);\n\n/**\n * SyncLocalStore proxy whose atomic transaction is owned by native SQLite.\n * The namespace argument never crosses the bridge; the native Auth principal\n * selected when the host was created is authoritative.\n */\nexport const createExpoSyncBridgeLocalStore = ({\n provider,\n storageSchema = { version: 1 },\n}: ExpoSyncBridgeLocalStoreOptions): SyncLocalStore => {\n const policy = resolveSyncLocalDataPolicy(storageSchema);\n const transaction = async <T>(\n _namespace: string,\n mode: SyncLocalStoreMode,\n run: (transaction: SyncLocalTransaction) => Promise<T>,\n ) => {\n const id = transactionId(\n await provider.request(\"sync.store.begin\", { mode }),\n );\n const request = (method: string, params: Record<string, unknown> = {}) =>\n provider.request(method, { ...params, transactionId: id });\n const remote: SyncLocalTransaction = {\n deleteCollection: async (key) => {\n await request(\"sync.tx.deleteCollection\", { key });\n },\n deleteMutation: async (operationId) => {\n await request(\"sync.tx.deleteMutation\", { operationId });\n },\n getCollection: async <R>(key: string) =>\n nullable<LocalCollectionRecord<R>>(\n await request(\"sync.tx.getCollection\", { key }),\n ),\n getInstallationId: async () =>\n nullable<string>(await request(\"sync.tx.getInstallationId\")),\n getMutation: async (operationId) =>\n nullable<LocalMutationRecord>(\n await request(\"sync.tx.getMutation\", { operationId }),\n ),\n listCollections: async () =>\n (await request(\"sync.tx.listCollections\")) as Array<{\n key: string;\n record: LocalCollectionRecord;\n }>,\n listMutations: async () =>\n (await request(\"sync.tx.listMutations\")) as LocalMutationRecord[],\n putCollection: async (key, collectionRecord) => {\n await request(\"sync.tx.putCollection\", {\n key,\n record: collectionRecord,\n });\n },\n putMutation: async (mutationRecord) => {\n await request(\"sync.tx.putMutation\", { record: mutationRecord });\n },\n resolveMutationPolicy: (name) =>\n resolveSyncLocalMutationPolicy(policy, name),\n setInstallationId: async (installationId) => {\n await request(\"sync.tx.setInstallationId\", { installationId });\n },\n };\n try {\n const result = await run(remote);\n await provider.request(\"sync.store.end\", {\n commit: true,\n transactionId: id,\n });\n\n return result;\n } catch (error) {\n await provider\n .request(\"sync.store.end\", {\n commit: false,\n transactionId: id,\n })\n .catch(() => undefined);\n throw error;\n }\n };\n\n return {\n deleteNamespace: async () => {\n await provider.request(\"sync.store.deleteNamespace\", {});\n },\n getSchemaStatus: async () =>\n nullable<SyncLocalStoreSchemaStatus>(\n await provider.request(\"sync.store.schema\", {}),\n ) ??\n (() => {\n throw new Error(\"Expo Sync native schema status is unavailable.\");\n })(),\n transaction,\n };\n};\n\nconst SOCKET_CHUNK_BYTES = 24 * 1024;\nconst MAX_SOCKET_FRAME_BYTES = 4 * 1024 * 1024;\nconst encodeBase64 = (value: Uint8Array) => {\n let binary = \"\";\n for (const byte of value) binary += String.fromCharCode(byte);\n\n return btoa(binary);\n};\nconst decodeBase64 = (value: string) =>\n Uint8Array.from(atob(value), (character) => character.charCodeAt(0));\n\ntype PendingMessage = {\n chunks: Array<Uint8Array | undefined>;\n timer: ReturnType<typeof setTimeout>;\n};\n\n/**\n * Browser-compatible string WebSocket facade backed by the native socket host.\n * Default JSON Sync frames are supported; binary serializers fail explicitly.\n */\nexport const createExpoSyncBridgeWebSocket = (\n provider: AbsoluteExpoSyncBridgeProvider,\n): typeof WebSocket => {\n class ExpoBridgeWebSocket extends EventTarget implements WebSocket {\n static readonly CLOSED = 3;\n static readonly CLOSING = 2;\n static readonly CONNECTING = 0;\n static readonly OPEN = 1;\n readonly CLOSED = 3;\n readonly CLOSING = 2;\n readonly CONNECTING = 0;\n readonly OPEN = 1;\n binaryType: BinaryType = \"blob\";\n readonly bufferedAmount = 0;\n readonly extensions = \"\";\n onclose: ((this: WebSocket, event: CloseEvent) => unknown) | null = null;\n onerror: ((this: WebSocket, event: Event) => unknown) | null = null;\n onmessage:\n | ((this: WebSocket, event: MessageEvent<unknown>) => unknown)\n | null = null;\n onopen: ((this: WebSocket, event: Event) => unknown) | null = null;\n readonly protocol = \"\";\n readyState = ExpoBridgeWebSocket.CONNECTING;\n readonly url: string;\n readonly #socketId = `websocket_${crypto.randomUUID()}`;\n readonly #messages = new Map<string, PendingMessage>();\n readonly #remove: () => void;\n #sendSequence = 0;\n #sendTail = Promise.resolve();\n\n constructor(url: string | URL, protocols?: string | string[]) {\n super();\n if (\n protocols !== undefined &&\n (typeof protocols !== \"string\" || protocols.length > 0) &&\n (!Array.isArray(protocols) || protocols.length > 0)\n )\n throw new TypeError(\n \"Expo Sync bridge does not support WebSocket subprotocols.\",\n );\n this.url = String(url);\n this.#remove = provider.on(\"sync.socket\", (payload) => {\n if (payload.socketId !== this.#socketId) return;\n this.#receive(payload);\n });\n void provider\n .request(\"sync.socket.open\", {\n socketId: this.#socketId,\n url: this.url,\n })\n .catch(() => this.#fail());\n }\n\n close(code?: number, reason?: string): void {\n if (\n this.readyState === ExpoBridgeWebSocket.CLOSED ||\n this.readyState === ExpoBridgeWebSocket.CLOSING\n )\n return;\n this.readyState = ExpoBridgeWebSocket.CLOSING;\n void provider\n .request(\"sync.socket.close\", {\n ...(code === undefined ? {} : { code }),\n ...(reason === undefined ? {} : { reason }),\n socketId: this.#socketId,\n })\n .catch(() => this.#closed(code ?? 1006, reason ?? \"\"));\n }\n\n ping(): void {\n throw new TypeError(\"Expo Sync bridge WebSocket ping is not supported.\");\n }\n\n send(data: string | ArrayBufferLike | Blob | ArrayBufferView): void {\n if (this.readyState !== ExpoBridgeWebSocket.OPEN)\n throw new DOMException(\"WebSocket is not open.\", \"InvalidStateError\");\n if (typeof data !== \"string\")\n throw new TypeError(\n \"Expo Sync bridge supports the default string serializer only.\",\n );\n const bytes = new TextEncoder().encode(data);\n if (bytes.byteLength > MAX_SOCKET_FRAME_BYTES)\n throw new DOMException(\n \"Sync frame exceeds 4 MiB.\",\n \"QuotaExceededError\",\n );\n const total = Math.max(\n 1,\n Math.ceil(bytes.byteLength / SOCKET_CHUNK_BYTES),\n );\n const messageId = `web_${(this.#sendSequence += 1).toString(36)}`;\n this.#sendTail = this.#sendTail\n .then(async () => {\n for (let index = 0; index < total; index += 1)\n await provider.request(\"sync.socket.sendChunk\", {\n data: encodeBase64(\n bytes.slice(\n index * SOCKET_CHUNK_BYTES,\n Math.min(bytes.byteLength, (index + 1) * SOCKET_CHUNK_BYTES),\n ),\n ),\n index,\n messageId,\n socketId: this.#socketId,\n total,\n });\n })\n .catch(() => this.#fail());\n }\n\n #dispatch<T extends Event>(\n event: T,\n listener: ((this: WebSocket, event: T) => unknown) | null,\n ) {\n this.dispatchEvent(event);\n listener?.call(this, event);\n }\n\n #closed(code: number, reason: string) {\n if (this.readyState === ExpoBridgeWebSocket.CLOSED) return;\n this.readyState = ExpoBridgeWebSocket.CLOSED;\n this.#remove();\n for (const message of this.#messages.values())\n clearTimeout(message.timer);\n this.#messages.clear();\n this.#dispatch(new CloseEvent(\"close\", { code, reason }), this.onclose);\n }\n\n #fail() {\n if (this.readyState === ExpoBridgeWebSocket.CLOSED) return;\n this.#dispatch(new Event(\"error\"), this.onerror);\n this.#closed(1006, \"\");\n }\n\n #receive(payload: Record<string, unknown>) {\n if (payload.type === \"open\") {\n if (this.readyState !== ExpoBridgeWebSocket.CONNECTING) return;\n this.readyState = ExpoBridgeWebSocket.OPEN;\n this.#dispatch(new Event(\"open\"), this.onopen);\n\n return;\n }\n if (payload.type === \"error\") {\n this.#dispatch(new Event(\"error\"), this.onerror);\n\n return;\n }\n if (payload.type === \"close\") {\n this.#closed(\n typeof payload.code === \"number\" ? payload.code : 1006,\n typeof payload.reason === \"string\" ? payload.reason : \"\",\n );\n\n return;\n }\n if (payload.type !== \"message-chunk\") return;\n const messageId = payload.messageId;\n const index = payload.index;\n const total = payload.total;\n const data = payload.data;\n if (\n typeof messageId !== \"string\" ||\n typeof index !== \"number\" ||\n !Number.isSafeInteger(index) ||\n typeof total !== \"number\" ||\n !Number.isSafeInteger(total) ||\n typeof data !== \"string\" ||\n index < 0 ||\n total < 1 ||\n index >= total ||\n total > Math.ceil(MAX_SOCKET_FRAME_BYTES / SOCKET_CHUNK_BYTES)\n ) {\n this.#fail();\n\n return;\n }\n let message = this.#messages.get(messageId);\n if (!message) {\n message = {\n chunks: Array.from({ length: total }),\n timer: setTimeout(() => this.#fail(), 10_000),\n };\n this.#messages.set(messageId, message);\n }\n if (message.chunks.length !== total || message.chunks[index]) {\n this.#fail();\n\n return;\n }\n try {\n message.chunks[index] = decodeBase64(data);\n } catch {\n this.#fail();\n\n return;\n }\n if (!message.chunks.every((chunk) => chunk !== undefined)) return;\n clearTimeout(message.timer);\n this.#messages.delete(messageId);\n const size = message.chunks.reduce(\n (sum, chunk) => sum + (chunk?.byteLength ?? 0),\n 0,\n );\n if (size > MAX_SOCKET_FRAME_BYTES) {\n this.#fail();\n\n return;\n }\n const bytes = new Uint8Array(size);\n let offset = 0;\n for (const chunk of message.chunks) {\n bytes.set(chunk!, offset);\n offset += chunk!.byteLength;\n }\n this.#dispatch(\n new MessageEvent(\"message\", {\n data: new TextDecoder().decode(bytes),\n }),\n this.onmessage,\n );\n }\n }\n\n return ExpoBridgeWebSocket as unknown as typeof WebSocket;\n};\n"
|
|
5
|
+
"import * as Crypto from \"expo-crypto\";\n\nexport const expoSyncRandomBytes = (length: number) =>\n Crypto.getRandomBytes(length);\n\nexport const expoSyncRandomId = () => Crypto.randomUUID();\n",
|
|
6
|
+
"import type {\n LocalCollectionRecord,\n LocalMutationRecord,\n SyncLocalStore,\n SyncLocalStoreMode,\n SyncLocalStoreSchemaInput,\n SyncLocalStoreSchemaStatus,\n SyncLocalTransaction,\n} from \"@absolutejs/sync/client\";\nimport { expoSyncRandomId } from \"./crypto\";\nimport {\n resolveSyncLocalDataPolicy,\n resolveSyncLocalMutationPolicy,\n} from \"@absolutejs/sync/client\";\n\nexport type AbsoluteExpoSyncBridgeProvider = {\n on(\n event: \"sync.socket\",\n listener: (payload: Record<string, unknown>) => void,\n ): () => void;\n request(method: string, params: Record<string, unknown>): Promise<unknown>;\n};\n\nexport type ExpoSyncBridgeLocalStoreOptions = {\n provider: AbsoluteExpoSyncBridgeProvider;\n storageSchema?: SyncLocalStoreSchemaInput;\n};\n\nconst record = (value: unknown, label: string) => {\n if (typeof value !== \"object\" || value === null || Array.isArray(value))\n throw new TypeError(`Expo Sync bridge returned invalid ${label}.`);\n\n return value as Record<string, unknown>;\n};\n\nconst transactionId = (value: unknown) => {\n const id = Reflect.get(record(value, \"transaction\"), \"transactionId\");\n if (typeof id !== \"string\" || id.length === 0)\n throw new TypeError(\"Expo Sync bridge returned an invalid transaction id.\");\n\n return id;\n};\n\nconst nullable = <T>(value: unknown): T | undefined =>\n value === null || value === undefined ? undefined : (value as T);\n\n/**\n * SyncLocalStore proxy whose atomic transaction is owned by native SQLite.\n * The namespace argument never crosses the bridge; the native Auth principal\n * selected when the host was created is authoritative.\n */\nexport const createExpoSyncBridgeLocalStore = ({\n provider,\n storageSchema = { version: 1 },\n}: ExpoSyncBridgeLocalStoreOptions): SyncLocalStore => {\n const policy = resolveSyncLocalDataPolicy(storageSchema);\n const transaction = async <T>(\n _namespace: string,\n mode: SyncLocalStoreMode,\n run: (transaction: SyncLocalTransaction) => Promise<T>,\n ) => {\n const id = transactionId(\n await provider.request(\"sync.store.begin\", { mode }),\n );\n const request = (method: string, params: Record<string, unknown> = {}) =>\n provider.request(method, { ...params, transactionId: id });\n const remote: SyncLocalTransaction = {\n deleteCollection: async (key) => {\n await request(\"sync.tx.deleteCollection\", { key });\n },\n deleteMutation: async (operationId) => {\n await request(\"sync.tx.deleteMutation\", { operationId });\n },\n getCollection: async <R>(key: string) =>\n nullable<LocalCollectionRecord<R>>(\n await request(\"sync.tx.getCollection\", { key }),\n ),\n getInstallationId: async () =>\n nullable<string>(await request(\"sync.tx.getInstallationId\")),\n getMutation: async (operationId) =>\n nullable<LocalMutationRecord>(\n await request(\"sync.tx.getMutation\", { operationId }),\n ),\n listCollections: async () =>\n (await request(\"sync.tx.listCollections\")) as Array<{\n key: string;\n record: LocalCollectionRecord;\n }>,\n listMutations: async () =>\n (await request(\"sync.tx.listMutations\")) as LocalMutationRecord[],\n putCollection: async (key, collectionRecord) => {\n await request(\"sync.tx.putCollection\", {\n key,\n record: collectionRecord,\n });\n },\n putMutation: async (mutationRecord) => {\n await request(\"sync.tx.putMutation\", { record: mutationRecord });\n },\n resolveMutationPolicy: (name) =>\n resolveSyncLocalMutationPolicy(policy, name),\n setInstallationId: async (installationId) => {\n await request(\"sync.tx.setInstallationId\", { installationId });\n },\n };\n try {\n const result = await run(remote);\n await provider.request(\"sync.store.end\", {\n commit: true,\n transactionId: id,\n });\n\n return result;\n } catch (error) {\n await provider\n .request(\"sync.store.end\", {\n commit: false,\n transactionId: id,\n })\n .catch(() => undefined);\n throw error;\n }\n };\n\n return {\n deleteNamespace: async () => {\n await provider.request(\"sync.store.deleteNamespace\", {});\n },\n getSchemaStatus: async () =>\n nullable<SyncLocalStoreSchemaStatus>(\n await provider.request(\"sync.store.schema\", {}),\n ) ??\n (() => {\n throw new Error(\"Expo Sync native schema status is unavailable.\");\n })(),\n transaction,\n };\n};\n\nconst SOCKET_CHUNK_BYTES = 24 * 1024;\nconst MAX_SOCKET_FRAME_BYTES = 4 * 1024 * 1024;\nconst encodeBase64 = (value: Uint8Array) => {\n let binary = \"\";\n for (const byte of value) binary += String.fromCharCode(byte);\n\n return btoa(binary);\n};\nconst decodeBase64 = (value: string) =>\n Uint8Array.from(atob(value), (character) => character.charCodeAt(0));\n\ntype PendingMessage = {\n chunks: Array<Uint8Array | undefined>;\n timer: ReturnType<typeof setTimeout>;\n};\n\n/**\n * Browser-compatible string WebSocket facade backed by the native socket host.\n * Default JSON Sync frames are supported; binary serializers fail explicitly.\n */\nexport const createExpoSyncBridgeWebSocket = (\n provider: AbsoluteExpoSyncBridgeProvider,\n): typeof WebSocket => {\n class ExpoBridgeWebSocket extends EventTarget implements WebSocket {\n static readonly CLOSED = 3;\n static readonly CLOSING = 2;\n static readonly CONNECTING = 0;\n static readonly OPEN = 1;\n readonly CLOSED = 3;\n readonly CLOSING = 2;\n readonly CONNECTING = 0;\n readonly OPEN = 1;\n binaryType: BinaryType = \"blob\";\n readonly bufferedAmount = 0;\n readonly extensions = \"\";\n onclose: ((this: WebSocket, event: CloseEvent) => unknown) | null = null;\n onerror: ((this: WebSocket, event: Event) => unknown) | null = null;\n onmessage:\n | ((this: WebSocket, event: MessageEvent<unknown>) => unknown)\n | null = null;\n onopen: ((this: WebSocket, event: Event) => unknown) | null = null;\n readonly protocol = \"\";\n readyState = ExpoBridgeWebSocket.CONNECTING;\n readonly url: string;\n readonly #socketId = `websocket_${expoSyncRandomId()}`;\n readonly #messages = new Map<string, PendingMessage>();\n readonly #remove: () => void;\n #sendSequence = 0;\n #sendTail = Promise.resolve();\n\n constructor(url: string | URL, protocols?: string | string[]) {\n super();\n if (\n protocols !== undefined &&\n (typeof protocols !== \"string\" || protocols.length > 0) &&\n (!Array.isArray(protocols) || protocols.length > 0)\n )\n throw new TypeError(\n \"Expo Sync bridge does not support WebSocket subprotocols.\",\n );\n this.url = String(url);\n this.#remove = provider.on(\"sync.socket\", (payload) => {\n if (payload.socketId !== this.#socketId) return;\n this.#receive(payload);\n });\n void provider\n .request(\"sync.socket.open\", {\n socketId: this.#socketId,\n url: this.url,\n })\n .catch(() => this.#fail());\n }\n\n close(code?: number, reason?: string): void {\n if (\n this.readyState === ExpoBridgeWebSocket.CLOSED ||\n this.readyState === ExpoBridgeWebSocket.CLOSING\n )\n return;\n this.readyState = ExpoBridgeWebSocket.CLOSING;\n void provider\n .request(\"sync.socket.close\", {\n ...(code === undefined ? {} : { code }),\n ...(reason === undefined ? {} : { reason }),\n socketId: this.#socketId,\n })\n .catch(() => this.#closed(code ?? 1006, reason ?? \"\"));\n }\n\n ping(): void {\n throw new TypeError(\"Expo Sync bridge WebSocket ping is not supported.\");\n }\n\n send(data: string | ArrayBufferLike | Blob | ArrayBufferView): void {\n if (this.readyState !== ExpoBridgeWebSocket.OPEN)\n throw new DOMException(\"WebSocket is not open.\", \"InvalidStateError\");\n if (typeof data !== \"string\")\n throw new TypeError(\n \"Expo Sync bridge supports the default string serializer only.\",\n );\n const bytes = new TextEncoder().encode(data);\n if (bytes.byteLength > MAX_SOCKET_FRAME_BYTES)\n throw new DOMException(\n \"Sync frame exceeds 4 MiB.\",\n \"QuotaExceededError\",\n );\n const total = Math.max(\n 1,\n Math.ceil(bytes.byteLength / SOCKET_CHUNK_BYTES),\n );\n const messageId = `web_${(this.#sendSequence += 1).toString(36)}`;\n this.#sendTail = this.#sendTail\n .then(async () => {\n for (let index = 0; index < total; index += 1)\n await provider.request(\"sync.socket.sendChunk\", {\n data: encodeBase64(\n bytes.slice(\n index * SOCKET_CHUNK_BYTES,\n Math.min(bytes.byteLength, (index + 1) * SOCKET_CHUNK_BYTES),\n ),\n ),\n index,\n messageId,\n socketId: this.#socketId,\n total,\n });\n })\n .catch(() => this.#fail());\n }\n\n #dispatch<T extends Event>(\n event: T,\n listener: ((this: WebSocket, event: T) => unknown) | null,\n ) {\n this.dispatchEvent(event);\n listener?.call(this, event);\n }\n\n #closed(code: number, reason: string) {\n if (this.readyState === ExpoBridgeWebSocket.CLOSED) return;\n this.readyState = ExpoBridgeWebSocket.CLOSED;\n this.#remove();\n for (const message of this.#messages.values())\n clearTimeout(message.timer);\n this.#messages.clear();\n this.#dispatch(new CloseEvent(\"close\", { code, reason }), this.onclose);\n }\n\n #fail() {\n if (this.readyState === ExpoBridgeWebSocket.CLOSED) return;\n this.#dispatch(new Event(\"error\"), this.onerror);\n this.#closed(1006, \"\");\n }\n\n #receive(payload: Record<string, unknown>) {\n if (payload.type === \"open\") {\n if (this.readyState !== ExpoBridgeWebSocket.CONNECTING) return;\n this.readyState = ExpoBridgeWebSocket.OPEN;\n this.#dispatch(new Event(\"open\"), this.onopen);\n\n return;\n }\n if (payload.type === \"error\") {\n this.#dispatch(new Event(\"error\"), this.onerror);\n\n return;\n }\n if (payload.type === \"close\") {\n this.#closed(\n typeof payload.code === \"number\" ? payload.code : 1006,\n typeof payload.reason === \"string\" ? payload.reason : \"\",\n );\n\n return;\n }\n if (payload.type !== \"message-chunk\") return;\n const messageId = payload.messageId;\n const index = payload.index;\n const total = payload.total;\n const data = payload.data;\n if (\n typeof messageId !== \"string\" ||\n typeof index !== \"number\" ||\n !Number.isSafeInteger(index) ||\n typeof total !== \"number\" ||\n !Number.isSafeInteger(total) ||\n typeof data !== \"string\" ||\n index < 0 ||\n total < 1 ||\n index >= total ||\n total > Math.ceil(MAX_SOCKET_FRAME_BYTES / SOCKET_CHUNK_BYTES)\n ) {\n this.#fail();\n\n return;\n }\n let message = this.#messages.get(messageId);\n if (!message) {\n message = {\n chunks: Array.from({ length: total }),\n timer: setTimeout(() => this.#fail(), 10_000),\n };\n this.#messages.set(messageId, message);\n }\n if (message.chunks.length !== total || message.chunks[index]) {\n this.#fail();\n\n return;\n }\n try {\n message.chunks[index] = decodeBase64(data);\n } catch {\n this.#fail();\n\n return;\n }\n if (!message.chunks.every((chunk) => chunk !== undefined)) return;\n clearTimeout(message.timer);\n this.#messages.delete(messageId);\n const size = message.chunks.reduce(\n (sum, chunk) => sum + (chunk?.byteLength ?? 0),\n 0,\n );\n if (size > MAX_SOCKET_FRAME_BYTES) {\n this.#fail();\n\n return;\n }\n const bytes = new Uint8Array(size);\n let offset = 0;\n for (const chunk of message.chunks) {\n bytes.set(chunk!, offset);\n offset += chunk!.byteLength;\n }\n this.#dispatch(\n new MessageEvent(\"message\", {\n data: new TextDecoder().decode(bytes),\n }),\n this.onmessage,\n );\n }\n }\n\n return ExpoBridgeWebSocket as unknown as typeof WebSocket;\n};\n"
|
|
6
7
|
],
|
|
7
|
-
"mappings": ";
|
|
8
|
-
"debugId": "
|
|
8
|
+
"mappings": "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",
|
|
9
|
+
"debugId": "456B48D3DEE2D99264756E2164756E21",
|
|
9
10
|
"names": []
|
|
10
11
|
}
|
package/dist/crypto.d.ts
ADDED
package/dist/index.d.ts
CHANGED
|
@@ -2,6 +2,7 @@ import type { SyncClient } from "@absolutejs/sync/client";
|
|
|
2
2
|
import type { SyncLocalProtectionProvider } from "@absolutejs/sync/client";
|
|
3
3
|
export * from "./store";
|
|
4
4
|
export * from "./bridge";
|
|
5
|
+
export { expoSyncRandomId } from "./crypto";
|
|
5
6
|
export type ExpoSyncSecureStore = {
|
|
6
7
|
AFTER_FIRST_UNLOCK_THIS_DEVICE_ONLY: number;
|
|
7
8
|
deleteItemAsync(key: string, options?: Record<string, unknown>): Promise<void>;
|