or3-provider-sqlite 0.0.6 → 0.0.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -146,7 +146,7 @@ All tables use snake_case aligned with the sync wire format.
146
146
 
147
147
  ### Sync semantics
148
148
 
149
- - **Push**: validates ops → checks `op_id` idempotency → allocates contiguous `server_version` block → writes change_log → applies LWW to materialized tables → upserts tombstones for deletes
149
+ - **Push**: validates ops (including a 256 KB serialized payload ceiling per operation) → checks `op_id` idempotency → allocates contiguous `server_version` block → writes change_log → applies LWW to materialized tables → upserts tombstones for deletes
150
150
  - **Pull**: returns ordered changes for `server_version > cursor` with limit/pagination and optional table filtering
151
151
  - **Snapshot**: captures canonical live rows and current tombstones at one `highWatermark`, then serves immutable, keyset-paginated pages ordered by `(tableName, pk, kind)`
152
152
  - **Cursor**: forward-only per-device cursor tracking
package/dist/module.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "or3-provider-sqlite",
3
3
  "configKey": "or3-provider-sqlite",
4
- "version": "0.0.6",
4
+ "version": "0.0.8",
5
5
  "builder": {
6
6
  "@nuxt/module-builder": "1.0.2",
7
7
  "unbuild": "3.6.1"
@@ -243,14 +243,7 @@ async function importRuntimeModule(moduleName) {
243
243
  return imported;
244
244
  }
245
245
  async function importCloudflareWorkersModule() {
246
- const imported = await import(
247
- /* @vite-ignore */
248
- "cloudflare:workers"
249
- );
250
- if (!isRecord(imported)) {
251
- throw new Error("cloudflare:workers did not export an object.");
252
- }
253
- return imported;
246
+ return importRuntimeModule("cloudflare:workers");
254
247
  }
255
248
  function isRecord(value) {
256
249
  return typeof value === "object" && value !== null;
@@ -277,10 +270,7 @@ async function createBetterSqliteDatabase(path) {
277
270
  async function createBunSqliteDatabase(path) {
278
271
  let imported;
279
272
  try {
280
- imported = await import(
281
- /* @vite-ignore */
282
- "bun:sqlite"
283
- );
273
+ imported = await importRuntimeModule("bun:sqlite");
284
274
  } catch (error) {
285
275
  throw new Error(
286
276
  "OR3_SQLITE_DRIVER=bun requires Bun and its built-in bun:sqlite module.",
@@ -21,6 +21,7 @@ const SNAPSHOT_TTL_SECONDS = 60 * 60;
21
21
  const SESSION_CONTEXT_KEY_PREFIX = "__or3_session_context_";
22
22
  const MIN_SYNC_RETENTION_SECONDS = 60 * 60;
23
23
  const MAX_SYNC_RETENTION_SECONDS = 365 * 24 * 60 * 60;
24
+ const MAX_SYNC_PAYLOAD_BYTES = 256 * 1024;
24
25
  function uid() {
25
26
  return globalThis.crypto.randomUUID();
26
27
  }
@@ -56,11 +57,15 @@ function validatePushOperation(workspaceId, op) {
56
57
  }
57
58
  const payload = op.payload;
58
59
  if (!payload) return void 0;
60
+ let serializedPayload;
59
61
  try {
60
- JSON.stringify(payload);
62
+ serializedPayload = JSON.stringify(payload);
61
63
  } catch {
62
64
  return `Invalid payload for ${op.tableName}: payload is not serializable`;
63
65
  }
66
+ if (new TextEncoder().encode(serializedPayload).byteLength > MAX_SYNC_PAYLOAD_BYTES) {
67
+ return `Payload too large for ${op.tableName}: exceeds ${MAX_SYNC_PAYLOAD_BYTES} bytes`;
68
+ }
64
69
  if ("_id" in payload) return `Invalid payload for ${op.tableName}: '_id' is immutable`;
65
70
  if ("workspace_id" in payload && payload.workspace_id !== workspaceId) {
66
71
  return `Invalid payload for ${op.tableName}: 'workspace_id' is immutable`;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "or3-provider-sqlite",
3
- "version": "0.0.6",
3
+ "version": "0.0.8",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "git+https://github.com/Saluana/or3-provider-sqlite.git"