@neetru/sdk 3.1.6 → 3.1.9

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.
Files changed (77) hide show
  1. package/dist/auth.cjs +65 -22
  2. package/dist/auth.cjs.map +1 -1
  3. package/dist/auth.d.cts +1 -1
  4. package/dist/auth.d.ts +1 -1
  5. package/dist/auth.mjs +65 -22
  6. package/dist/auth.mjs.map +1 -1
  7. package/dist/catalog.cjs.map +1 -1
  8. package/dist/catalog.d.cts +1 -1
  9. package/dist/catalog.d.ts +1 -1
  10. package/dist/catalog.mjs.map +1 -1
  11. package/dist/checkout.cjs.map +1 -1
  12. package/dist/checkout.d.cts +1 -1
  13. package/dist/checkout.d.ts +1 -1
  14. package/dist/checkout.mjs.map +1 -1
  15. package/dist/db-react.d.cts +1 -1
  16. package/dist/db-react.d.ts +1 -1
  17. package/dist/db.cjs +55 -16
  18. package/dist/db.cjs.map +1 -1
  19. package/dist/db.d.cts +1 -1
  20. package/dist/db.d.ts +1 -1
  21. package/dist/db.mjs +55 -16
  22. package/dist/db.mjs.map +1 -1
  23. package/dist/entitlements.cjs.map +1 -1
  24. package/dist/entitlements.d.cts +1 -1
  25. package/dist/entitlements.d.ts +1 -1
  26. package/dist/entitlements.mjs.map +1 -1
  27. package/dist/errors.cjs.map +1 -1
  28. package/dist/errors.d.cts +8 -8
  29. package/dist/errors.d.ts +8 -8
  30. package/dist/errors.mjs.map +1 -1
  31. package/dist/firestore-compat.cjs +4 -9
  32. package/dist/firestore-compat.cjs.map +1 -1
  33. package/dist/firestore-compat.d.cts +2 -2
  34. package/dist/firestore-compat.d.ts +2 -2
  35. package/dist/firestore-compat.mjs +4 -9
  36. package/dist/firestore-compat.mjs.map +1 -1
  37. package/dist/index.cjs +66 -23
  38. package/dist/index.cjs.map +1 -1
  39. package/dist/index.d.cts +2 -2
  40. package/dist/index.d.ts +2 -2
  41. package/dist/index.mjs +66 -23
  42. package/dist/index.mjs.map +1 -1
  43. package/dist/mocks.cjs.map +1 -1
  44. package/dist/mocks.d.cts +1 -1
  45. package/dist/mocks.d.ts +1 -1
  46. package/dist/mocks.mjs.map +1 -1
  47. package/dist/notifications.cjs.map +1 -1
  48. package/dist/notifications.d.cts +1 -1
  49. package/dist/notifications.d.ts +1 -1
  50. package/dist/notifications.mjs.map +1 -1
  51. package/dist/react.cjs.map +1 -1
  52. package/dist/react.d.cts +1 -1
  53. package/dist/react.d.ts +1 -1
  54. package/dist/react.mjs.map +1 -1
  55. package/dist/support.cjs.map +1 -1
  56. package/dist/support.d.cts +1 -1
  57. package/dist/support.d.ts +1 -1
  58. package/dist/support.mjs.map +1 -1
  59. package/dist/telemetry.cjs +5 -1
  60. package/dist/telemetry.cjs.map +1 -1
  61. package/dist/telemetry.d.cts +1 -1
  62. package/dist/telemetry.d.ts +1 -1
  63. package/dist/telemetry.mjs +5 -1
  64. package/dist/telemetry.mjs.map +1 -1
  65. package/dist/{types-BXvGHppn.d.cts → types-DDiVzgCT.d.cts} +19 -2
  66. package/dist/{types-CQVak2a3.d.ts → types-HWDOUmlC.d.ts} +19 -2
  67. package/dist/usage.cjs +2 -2
  68. package/dist/usage.cjs.map +1 -1
  69. package/dist/usage.d.cts +1 -1
  70. package/dist/usage.d.ts +1 -1
  71. package/dist/usage.mjs +2 -2
  72. package/dist/usage.mjs.map +1 -1
  73. package/dist/webhooks.cjs.map +1 -1
  74. package/dist/webhooks.d.cts +1 -1
  75. package/dist/webhooks.d.ts +1 -1
  76. package/dist/webhooks.mjs.map +1 -1
  77. package/package.json +156 -156
package/dist/db.d.cts CHANGED
@@ -1,3 +1,3 @@
1
- export { j as ConflictRecord, k as CreateOfflineDocumentsOptions, m as DbBatchOp, n as DbChangeType, o as DbCollectionRef, p as DbDoc, q as DbDocRef, r as DbGetResult, s as DbListResult, u as DbQuery, v as DbSqlLease, x as DbWhereFilter, F as FieldSentinel, I as IncrementSentinel, N as NEETRU_SENTINEL_KEY, H as NeetruDb, J as NeetruDbDocuments, K as NeetruDbEngine, O as NeetruDbError, P as NeetruDbErrorCode, Q as NeetruDbOptions, R as NeetruDbTransport, T as NeetruSqlClient, a0 as RealtimeTransport, a5 as ServerTimestampSentinel, a7 as SqlOptions, ac as SyncState, at as WithFieldSentinels, av as createNeetruDb, ax as createRestSyncTransport, az as getWebSocketRealtimeClient, aA as increment, aB as isFieldSentinel, aC as isIncrementSentinel, aD as isServerTimestampSentinel, aE as serverTimestamp } from './types-BXvGHppn.cjs';
1
+ export { j as ConflictRecord, k as CreateOfflineDocumentsOptions, m as DbBatchOp, n as DbChangeType, o as DbCollectionRef, p as DbDoc, q as DbDocRef, r as DbGetResult, s as DbListResult, u as DbQuery, v as DbSqlLease, x as DbWhereFilter, F as FieldSentinel, I as IncrementSentinel, N as NEETRU_SENTINEL_KEY, H as NeetruDb, J as NeetruDbDocuments, K as NeetruDbEngine, O as NeetruDbError, P as NeetruDbErrorCode, Q as NeetruDbOptions, R as NeetruDbTransport, T as NeetruSqlClient, a0 as RealtimeTransport, a5 as ServerTimestampSentinel, a7 as SqlOptions, ac as SyncState, at as WithFieldSentinels, av as createNeetruDb, ax as createRestSyncTransport, az as getWebSocketRealtimeClient, aA as increment, aB as isFieldSentinel, aC as isIncrementSentinel, aD as isServerTimestampSentinel, aE as serverTimestamp } from './types-DDiVzgCT.cjs';
2
2
  import 'drizzle-orm/node-postgres';
3
3
  import './errors.cjs';
package/dist/db.d.ts CHANGED
@@ -1,3 +1,3 @@
1
- export { j as ConflictRecord, k as CreateOfflineDocumentsOptions, m as DbBatchOp, n as DbChangeType, o as DbCollectionRef, p as DbDoc, q as DbDocRef, r as DbGetResult, s as DbListResult, u as DbQuery, v as DbSqlLease, x as DbWhereFilter, F as FieldSentinel, I as IncrementSentinel, N as NEETRU_SENTINEL_KEY, H as NeetruDb, J as NeetruDbDocuments, K as NeetruDbEngine, O as NeetruDbError, P as NeetruDbErrorCode, Q as NeetruDbOptions, R as NeetruDbTransport, T as NeetruSqlClient, a0 as RealtimeTransport, a5 as ServerTimestampSentinel, a7 as SqlOptions, ac as SyncState, at as WithFieldSentinels, av as createNeetruDb, ax as createRestSyncTransport, az as getWebSocketRealtimeClient, aA as increment, aB as isFieldSentinel, aC as isIncrementSentinel, aD as isServerTimestampSentinel, aE as serverTimestamp } from './types-CQVak2a3.js';
1
+ export { j as ConflictRecord, k as CreateOfflineDocumentsOptions, m as DbBatchOp, n as DbChangeType, o as DbCollectionRef, p as DbDoc, q as DbDocRef, r as DbGetResult, s as DbListResult, u as DbQuery, v as DbSqlLease, x as DbWhereFilter, F as FieldSentinel, I as IncrementSentinel, N as NEETRU_SENTINEL_KEY, H as NeetruDb, J as NeetruDbDocuments, K as NeetruDbEngine, O as NeetruDbError, P as NeetruDbErrorCode, Q as NeetruDbOptions, R as NeetruDbTransport, T as NeetruSqlClient, a0 as RealtimeTransport, a5 as ServerTimestampSentinel, a7 as SqlOptions, ac as SyncState, at as WithFieldSentinels, av as createNeetruDb, ax as createRestSyncTransport, az as getWebSocketRealtimeClient, aA as increment, aB as isFieldSentinel, aC as isIncrementSentinel, aD as isServerTimestampSentinel, aE as serverTimestamp } from './types-HWDOUmlC.js';
2
2
  import 'drizzle-orm/node-postgres';
3
3
  import './errors.js';
package/dist/db.mjs CHANGED
@@ -445,7 +445,7 @@ __export(sql_client_exports, {
445
445
  function mapEnvToCore(sdkEnv) {
446
446
  if (sdkEnv === "workspace") return "staging";
447
447
  if (sdkEnv === "prod") return "production";
448
- return "dev";
448
+ return "dev-local";
449
449
  }
450
450
  function createHttpLeaseFetcher(config) {
451
451
  return async (opts) => {
@@ -704,7 +704,12 @@ function evaluateFilter(data, filter) {
704
704
  if (!Array.isArray(value)) return true;
705
705
  return !value.includes(fieldValue);
706
706
  default:
707
- return false;
707
+ if (op === "array-contains-any") {
708
+ return Array.isArray(fieldValue) && Array.isArray(value) && value.some((v) => fieldValue.includes(v));
709
+ }
710
+ throw new Error(
711
+ `QueryEngine: operador de filtro '${String(op)}' n\xE3o suportado em leitura offline/cache. Use um operador suportado (==, !=, <, <=, >, >=, array-contains, array-contains-any, in, not-in) ou fa\xE7a a query server-side.`
712
+ );
708
713
  }
709
714
  }
710
715
  function matchesAllFilters(data, filters) {
@@ -1234,7 +1239,7 @@ var MutationQueue = class {
1234
1239
  * - `{ removed: true }` — a mutação existente deve ser deletada (add+remove)
1235
1240
  * - `null` — não é possível coalescir
1236
1241
  */
1237
- tryCoalesce(existing, newOp, newPayload, newBatchId) {
1242
+ tryCoalesce(existing, newOp, newPayload, newBatchId, newUpsert) {
1238
1243
  if (existing.batchId !== newBatchId) return null;
1239
1244
  if (existing.status === "inflight") return null;
1240
1245
  const existingOp = existing.op;
@@ -1242,10 +1247,12 @@ var MutationQueue = class {
1242
1247
  return { removed: true };
1243
1248
  }
1244
1249
  if (existingOp === "update" && newOp === "update") {
1250
+ const mergedUpsert = existing.upsert || newUpsert;
1245
1251
  return {
1246
1252
  coalesced: {
1247
1253
  ...existing,
1248
- payload: { ...existing.payload ?? {}, ...newPayload ?? {} }
1254
+ payload: { ...existing.payload ?? {}, ...newPayload ?? {} },
1255
+ ...mergedUpsert ? { upsert: true } : {}
1249
1256
  }
1250
1257
  };
1251
1258
  }
@@ -1294,13 +1301,13 @@ var MutationQueue = class {
1294
1301
  * Atômico: a persistência final é uma única operação putMutation.
1295
1302
  */
1296
1303
  async enqueue(params) {
1297
- const { collection, op, payload, baseVersion, batchId } = params;
1304
+ const { collection, op, payload, baseVersion, batchId, upsert } = params;
1298
1305
  const docId = params.docId ?? (op === "add" ? generateUUIDv4() : "");
1299
1306
  await this.syncSeq();
1300
1307
  const existingMutations = await this.store.listMutations({ collection, docId });
1301
1308
  const lastQueued = existingMutations.filter((m) => m.status === "queued").sort((a, b) => b.seq - a.seq)[0];
1302
1309
  if (lastQueued !== void 0) {
1303
- const coalesceResult = this.tryCoalesce(lastQueued, op, payload, batchId);
1310
+ const coalesceResult = this.tryCoalesce(lastQueued, op, payload, batchId, upsert);
1304
1311
  if (coalesceResult !== null) {
1305
1312
  if ("removed" in coalesceResult) {
1306
1313
  await this.store.deleteMutation(lastQueued.mutationId);
@@ -1338,7 +1345,9 @@ var MutationQueue = class {
1338
1345
  attempts: 0,
1339
1346
  lastError: null,
1340
1347
  status: "queued",
1341
- batchId
1348
+ batchId,
1349
+ // bug_0273e4dd: só persiste o flag quando verdadeiro (mantém o doc limpo).
1350
+ ...upsert ? { upsert: true } : {}
1342
1351
  };
1343
1352
  await this.store.putMutation(mutation);
1344
1353
  return mutation;
@@ -1678,10 +1687,15 @@ var SyncEngine = class {
1678
1687
  await this._applyRejected(mut, res, busChanges);
1679
1688
  }
1680
1689
  }
1690
+ const processedIds = new Set(result.results.map((r) => r.mutationId));
1691
+ const unprocessed = mutations.filter((m) => !processedIds.has(m.mutationId));
1692
+ for (const mut of unprocessed) {
1693
+ await this._queue.markRetry(mut.mutationId, "partial_push: muta\xE7\xE3o n\xE3o processada no lote");
1694
+ }
1681
1695
  if (busChanges.length > 0) {
1682
1696
  this._bus.emit(busChanges);
1683
1697
  }
1684
- return true;
1698
+ return unprocessed.length === 0;
1685
1699
  }
1686
1700
  /** Atualiza o cache após confirmação de escrita (outcome=confirmed). */
1687
1701
  async _applySyncedDoc(collection, docId, serverVersion, serverTimestamp2, mut, busChanges) {
@@ -2988,7 +3002,7 @@ var DbCollectionRefImpl = class {
2988
3002
  }]);
2989
3003
  return { ok: true };
2990
3004
  }
2991
- async update(id, data) {
3005
+ async update(id, data, opts) {
2992
3006
  assertValidId(id);
2993
3007
  const existing = await this._store.getDoc(this._collection, id);
2994
3008
  const rawData = data;
@@ -3001,7 +3015,9 @@ var DbCollectionRefImpl = class {
3001
3015
  op: "update",
3002
3016
  payload: rawData,
3003
3017
  baseVersion: existing?.meta.serverVersion ?? null,
3004
- batchId: null
3018
+ batchId: null,
3019
+ // bug_0273e4dd: propaga merge-upsert (setDoc({merge:true}) cria-se-ausente).
3020
+ upsert: opts?.upsert
3005
3021
  });
3006
3022
  await this._store.putDoc({
3007
3023
  collection: this._collection,
@@ -3125,7 +3141,9 @@ var DbCollectionRefImpl = class {
3125
3141
  op: "update",
3126
3142
  payload: data,
3127
3143
  baseVersion: existing?.meta.serverVersion ?? null,
3128
- batchId
3144
+ batchId,
3145
+ // bug_0273e4dd: propaga merge-upsert (writeBatch.set(merge) cria-se-ausente).
3146
+ upsert: op.upsert
3129
3147
  });
3130
3148
  await this._store.putDoc({
3131
3149
  collection,
@@ -3387,6 +3405,10 @@ async function createOfflineDocumentsNamespace(opts) {
3387
3405
  connectivity,
3388
3406
  periodicSyncIntervalMs: opts.periodicSyncIntervalMs ?? 5 * 60 * 1e3
3389
3407
  });
3408
+ connectivity.start();
3409
+ if (!opts.singleTab && tabCoordinatorLike instanceof TabCoordinator) {
3410
+ tabCoordinatorLike.start();
3411
+ }
3390
3412
  return new NeetruDbDocumentsImpl({
3391
3413
  store,
3392
3414
  queue,
@@ -3857,11 +3879,11 @@ function createRestSyncTransport(config) {
3857
3879
  let raw;
3858
3880
  if (m.op === "add") {
3859
3881
  raw = await httpRequest2(config, {
3860
- method: "POST",
3861
- path: DATASTORE_COLLECTION_ENDPOINT(m.collection),
3882
+ method: "PUT",
3883
+ path: DATASTORE_DOC_ENDPOINT(m.collection, m.docId),
3862
3884
  body: { data: m.payload ?? {} },
3863
3885
  requireAuth: true,
3864
- retries: 0,
3886
+ retries: 2,
3865
3887
  headers: tenantHeaders
3866
3888
  });
3867
3889
  } else if (m.op === "set") {
@@ -3877,7 +3899,7 @@ function createRestSyncTransport(config) {
3877
3899
  raw = await httpRequest2(config, {
3878
3900
  method: "PATCH",
3879
3901
  path: DATASTORE_DOC_ENDPOINT(m.collection, m.docId),
3880
- body: { data: m.payload ?? {} },
3902
+ body: { data: m.payload ?? {}, ...m.upsert ? { upsert: true } : {} },
3881
3903
  requireAuth: true,
3882
3904
  retries: 2,
3883
3905
  headers: tenantHeaders
@@ -3900,7 +3922,24 @@ function createRestSyncTransport(config) {
3900
3922
  });
3901
3923
  } catch (err) {
3902
3924
  const msg = err instanceof Error ? err.message : String(err);
3903
- throw new NeetruDbError("db_unavailable", `pushMutations falhou: ${msg}`);
3925
+ const code = err?.code;
3926
+ const status = err?.status;
3927
+ const isPermanent = code === "forbidden" || code === "unauthorized" || code === "not_found" || code === "conflict" || code === "validation_failed" || typeof status === "number" && status >= 400 && status < 500 && status !== 408 && status !== 429;
3928
+ if (isPermanent) {
3929
+ const reason = code === "forbidden" || code === "unauthorized" ? "rejected_permission" : "rejected_validation";
3930
+ results.push({
3931
+ mutationId: m.mutationId,
3932
+ outcome: "rejected",
3933
+ reason,
3934
+ serverVersion: null,
3935
+ serverData: null
3936
+ });
3937
+ continue;
3938
+ }
3939
+ if (results.length === 0) {
3940
+ throw new NeetruDbError("db_unavailable", `pushMutations falhou: ${msg}`);
3941
+ }
3942
+ break;
3904
3943
  }
3905
3944
  }
3906
3945
  return { results };