@neetru/sdk 3.1.7 → 3.1.10

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 (69) hide show
  1. package/dist/ai.cjs +304 -0
  2. package/dist/ai.cjs.map +1 -0
  3. package/dist/ai.d.cts +3 -0
  4. package/dist/ai.d.ts +3 -0
  5. package/dist/ai.mjs +302 -0
  6. package/dist/ai.mjs.map +1 -0
  7. package/dist/auth.cjs +348 -23
  8. package/dist/auth.cjs.map +1 -1
  9. package/dist/auth.d.cts +1 -1
  10. package/dist/auth.d.ts +1 -1
  11. package/dist/auth.mjs +348 -23
  12. package/dist/auth.mjs.map +1 -1
  13. package/dist/catalog.d.cts +1 -1
  14. package/dist/catalog.d.ts +1 -1
  15. package/dist/checkout.d.cts +1 -1
  16. package/dist/checkout.d.ts +1 -1
  17. package/dist/db-react.d.cts +1 -1
  18. package/dist/db-react.d.ts +1 -1
  19. package/dist/db.cjs +55 -16
  20. package/dist/db.cjs.map +1 -1
  21. package/dist/db.d.cts +1 -1
  22. package/dist/db.d.ts +1 -1
  23. package/dist/db.mjs +55 -16
  24. package/dist/db.mjs.map +1 -1
  25. package/dist/entitlements.d.cts +1 -1
  26. package/dist/entitlements.d.ts +1 -1
  27. package/dist/firestore-compat.cjs +4 -9
  28. package/dist/firestore-compat.cjs.map +1 -1
  29. package/dist/firestore-compat.d.cts +2 -2
  30. package/dist/firestore-compat.d.ts +2 -2
  31. package/dist/firestore-compat.mjs +4 -9
  32. package/dist/firestore-compat.mjs.map +1 -1
  33. package/dist/index.cjs +351 -24
  34. package/dist/index.cjs.map +1 -1
  35. package/dist/index.d.cts +3 -3
  36. package/dist/index.d.ts +3 -3
  37. package/dist/index.mjs +350 -25
  38. package/dist/index.mjs.map +1 -1
  39. package/dist/mocks.cjs +52 -0
  40. package/dist/mocks.cjs.map +1 -1
  41. package/dist/mocks.d.cts +20 -2
  42. package/dist/mocks.d.ts +20 -2
  43. package/dist/mocks.mjs +52 -1
  44. package/dist/mocks.mjs.map +1 -1
  45. package/dist/notifications.d.cts +1 -1
  46. package/dist/notifications.d.ts +1 -1
  47. package/dist/react.cjs.map +1 -1
  48. package/dist/react.d.cts +1 -1
  49. package/dist/react.d.ts +1 -1
  50. package/dist/react.mjs.map +1 -1
  51. package/dist/support.d.cts +1 -1
  52. package/dist/support.d.ts +1 -1
  53. package/dist/telemetry.cjs +5 -1
  54. package/dist/telemetry.cjs.map +1 -1
  55. package/dist/telemetry.d.cts +1 -1
  56. package/dist/telemetry.d.ts +1 -1
  57. package/dist/telemetry.mjs +5 -1
  58. package/dist/telemetry.mjs.map +1 -1
  59. package/dist/{types-BXvGHppn.d.cts → types-Cog9S-tC.d.cts} +103 -3
  60. package/dist/{types-CQVak2a3.d.ts → types-dagUxKYz.d.ts} +103 -3
  61. package/dist/usage.cjs +2 -2
  62. package/dist/usage.cjs.map +1 -1
  63. package/dist/usage.d.cts +1 -1
  64. package/dist/usage.d.ts +1 -1
  65. package/dist/usage.mjs +2 -2
  66. package/dist/usage.mjs.map +1 -1
  67. package/dist/webhooks.d.cts +1 -1
  68. package/dist/webhooks.d.ts +1 -1
  69. package/package.json +6 -1
@@ -1,4 +1,4 @@
1
- import { a3 as ResolvedConfig, C as CatalogListOptions, b as CatalogListResponse, X as Product } from './types-BXvGHppn.cjs';
1
+ import { ab as ResolvedConfig, C as CatalogListOptions, j as CatalogListResponse, a3 as Product } from './types-Cog9S-tC.cjs';
2
2
  import 'drizzle-orm/node-postgres';
3
3
  import './errors.cjs';
4
4
 
package/dist/catalog.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { a3 as ResolvedConfig, C as CatalogListOptions, b as CatalogListResponse, X as Product } from './types-CQVak2a3.js';
1
+ import { ab as ResolvedConfig, C as CatalogListOptions, j as CatalogListResponse, a3 as Product } from './types-dagUxKYz.js';
2
2
  import 'drizzle-orm/node-postgres';
3
3
  import './errors.js';
4
4
 
@@ -1,3 +1,3 @@
1
- export { c as CheckoutAuthOpts, d as CheckoutIntentInfo, e as CheckoutIntentStatus, f as CheckoutNamespace, g as CheckoutStartInput, h as CheckoutStartResult, i as CheckoutTenantType, M as MockCheckout, au as createCheckoutNamespace } from './types-BXvGHppn.cjs';
1
+ export { k as CheckoutAuthOpts, l as CheckoutIntentInfo, m as CheckoutIntentStatus, n as CheckoutNamespace, o as CheckoutStartInput, p as CheckoutStartResult, q as CheckoutTenantType, N as MockCheckout, aD as createCheckoutNamespace } from './types-Cog9S-tC.cjs';
2
2
  import 'drizzle-orm/node-postgres';
3
3
  import './errors.cjs';
@@ -1,3 +1,3 @@
1
- export { c as CheckoutAuthOpts, d as CheckoutIntentInfo, e as CheckoutIntentStatus, f as CheckoutNamespace, g as CheckoutStartInput, h as CheckoutStartResult, i as CheckoutTenantType, M as MockCheckout, au as createCheckoutNamespace } from './types-CQVak2a3.js';
1
+ export { k as CheckoutAuthOpts, l as CheckoutIntentInfo, m as CheckoutIntentStatus, n as CheckoutNamespace, o as CheckoutStartInput, p as CheckoutStartResult, q as CheckoutTenantType, N as MockCheckout, aD as createCheckoutNamespace } from './types-dagUxKYz.js';
2
2
  import 'drizzle-orm/node-postgres';
3
3
  import './errors.js';
@@ -1,4 +1,4 @@
1
- import { ac as SyncState, ah as Unsubscribe, p as DbDoc, B as NeetruClient, o as DbCollectionRef, u as DbQuery } from './types-BXvGHppn.cjs';
1
+ import { ak as SyncState, ap as Unsubscribe, x as DbDoc, R as NeetruClient, w as DbCollectionRef, F as DbQuery } from './types-Cog9S-tC.cjs';
2
2
  import 'drizzle-orm/node-postgres';
3
3
  import './errors.cjs';
4
4
 
@@ -1,4 +1,4 @@
1
- import { ac as SyncState, ah as Unsubscribe, p as DbDoc, B as NeetruClient, o as DbCollectionRef, u as DbQuery } from './types-CQVak2a3.js';
1
+ import { ak as SyncState, ap as Unsubscribe, x as DbDoc, R as NeetruClient, w as DbCollectionRef, F as DbQuery } from './types-dagUxKYz.js';
2
2
  import 'drizzle-orm/node-postgres';
3
3
  import './errors.js';
4
4
 
package/dist/db.cjs CHANGED
@@ -447,7 +447,7 @@ __export(sql_client_exports, {
447
447
  function mapEnvToCore(sdkEnv) {
448
448
  if (sdkEnv === "workspace") return "staging";
449
449
  if (sdkEnv === "prod") return "production";
450
- return "dev";
450
+ return "dev-local";
451
451
  }
452
452
  function createHttpLeaseFetcher(config) {
453
453
  return async (opts) => {
@@ -706,7 +706,12 @@ function evaluateFilter(data, filter) {
706
706
  if (!Array.isArray(value)) return true;
707
707
  return !value.includes(fieldValue);
708
708
  default:
709
- return false;
709
+ if (op === "array-contains-any") {
710
+ return Array.isArray(fieldValue) && Array.isArray(value) && value.some((v) => fieldValue.includes(v));
711
+ }
712
+ throw new Error(
713
+ `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.`
714
+ );
710
715
  }
711
716
  }
712
717
  function matchesAllFilters(data, filters) {
@@ -1236,7 +1241,7 @@ var MutationQueue = class {
1236
1241
  * - `{ removed: true }` — a mutação existente deve ser deletada (add+remove)
1237
1242
  * - `null` — não é possível coalescir
1238
1243
  */
1239
- tryCoalesce(existing, newOp, newPayload, newBatchId) {
1244
+ tryCoalesce(existing, newOp, newPayload, newBatchId, newUpsert) {
1240
1245
  if (existing.batchId !== newBatchId) return null;
1241
1246
  if (existing.status === "inflight") return null;
1242
1247
  const existingOp = existing.op;
@@ -1244,10 +1249,12 @@ var MutationQueue = class {
1244
1249
  return { removed: true };
1245
1250
  }
1246
1251
  if (existingOp === "update" && newOp === "update") {
1252
+ const mergedUpsert = existing.upsert || newUpsert;
1247
1253
  return {
1248
1254
  coalesced: {
1249
1255
  ...existing,
1250
- payload: { ...existing.payload ?? {}, ...newPayload ?? {} }
1256
+ payload: { ...existing.payload ?? {}, ...newPayload ?? {} },
1257
+ ...mergedUpsert ? { upsert: true } : {}
1251
1258
  }
1252
1259
  };
1253
1260
  }
@@ -1296,13 +1303,13 @@ var MutationQueue = class {
1296
1303
  * Atômico: a persistência final é uma única operação putMutation.
1297
1304
  */
1298
1305
  async enqueue(params) {
1299
- const { collection, op, payload, baseVersion, batchId } = params;
1306
+ const { collection, op, payload, baseVersion, batchId, upsert } = params;
1300
1307
  const docId = params.docId ?? (op === "add" ? generateUUIDv4() : "");
1301
1308
  await this.syncSeq();
1302
1309
  const existingMutations = await this.store.listMutations({ collection, docId });
1303
1310
  const lastQueued = existingMutations.filter((m) => m.status === "queued").sort((a, b) => b.seq - a.seq)[0];
1304
1311
  if (lastQueued !== void 0) {
1305
- const coalesceResult = this.tryCoalesce(lastQueued, op, payload, batchId);
1312
+ const coalesceResult = this.tryCoalesce(lastQueued, op, payload, batchId, upsert);
1306
1313
  if (coalesceResult !== null) {
1307
1314
  if ("removed" in coalesceResult) {
1308
1315
  await this.store.deleteMutation(lastQueued.mutationId);
@@ -1340,7 +1347,9 @@ var MutationQueue = class {
1340
1347
  attempts: 0,
1341
1348
  lastError: null,
1342
1349
  status: "queued",
1343
- batchId
1350
+ batchId,
1351
+ // bug_0273e4dd: só persiste o flag quando verdadeiro (mantém o doc limpo).
1352
+ ...upsert ? { upsert: true } : {}
1344
1353
  };
1345
1354
  await this.store.putMutation(mutation);
1346
1355
  return mutation;
@@ -1680,10 +1689,15 @@ var SyncEngine = class {
1680
1689
  await this._applyRejected(mut, res, busChanges);
1681
1690
  }
1682
1691
  }
1692
+ const processedIds = new Set(result.results.map((r) => r.mutationId));
1693
+ const unprocessed = mutations.filter((m) => !processedIds.has(m.mutationId));
1694
+ for (const mut of unprocessed) {
1695
+ await this._queue.markRetry(mut.mutationId, "partial_push: muta\xE7\xE3o n\xE3o processada no lote");
1696
+ }
1683
1697
  if (busChanges.length > 0) {
1684
1698
  this._bus.emit(busChanges);
1685
1699
  }
1686
- return true;
1700
+ return unprocessed.length === 0;
1687
1701
  }
1688
1702
  /** Atualiza o cache após confirmação de escrita (outcome=confirmed). */
1689
1703
  async _applySyncedDoc(collection, docId, serverVersion, serverTimestamp2, mut, busChanges) {
@@ -2990,7 +3004,7 @@ var DbCollectionRefImpl = class {
2990
3004
  }]);
2991
3005
  return { ok: true };
2992
3006
  }
2993
- async update(id, data) {
3007
+ async update(id, data, opts) {
2994
3008
  assertValidId(id);
2995
3009
  const existing = await this._store.getDoc(this._collection, id);
2996
3010
  const rawData = data;
@@ -3003,7 +3017,9 @@ var DbCollectionRefImpl = class {
3003
3017
  op: "update",
3004
3018
  payload: rawData,
3005
3019
  baseVersion: existing?.meta.serverVersion ?? null,
3006
- batchId: null
3020
+ batchId: null,
3021
+ // bug_0273e4dd: propaga merge-upsert (setDoc({merge:true}) cria-se-ausente).
3022
+ upsert: opts?.upsert
3007
3023
  });
3008
3024
  await this._store.putDoc({
3009
3025
  collection: this._collection,
@@ -3127,7 +3143,9 @@ var DbCollectionRefImpl = class {
3127
3143
  op: "update",
3128
3144
  payload: data,
3129
3145
  baseVersion: existing?.meta.serverVersion ?? null,
3130
- batchId
3146
+ batchId,
3147
+ // bug_0273e4dd: propaga merge-upsert (writeBatch.set(merge) cria-se-ausente).
3148
+ upsert: op.upsert
3131
3149
  });
3132
3150
  await this._store.putDoc({
3133
3151
  collection,
@@ -3389,6 +3407,10 @@ async function createOfflineDocumentsNamespace(opts) {
3389
3407
  connectivity,
3390
3408
  periodicSyncIntervalMs: opts.periodicSyncIntervalMs ?? 5 * 60 * 1e3
3391
3409
  });
3410
+ connectivity.start();
3411
+ if (!opts.singleTab && tabCoordinatorLike instanceof TabCoordinator) {
3412
+ tabCoordinatorLike.start();
3413
+ }
3392
3414
  return new NeetruDbDocumentsImpl({
3393
3415
  store,
3394
3416
  queue,
@@ -3859,11 +3881,11 @@ function createRestSyncTransport(config) {
3859
3881
  let raw;
3860
3882
  if (m.op === "add") {
3861
3883
  raw = await httpRequest2(config, {
3862
- method: "POST",
3863
- path: DATASTORE_COLLECTION_ENDPOINT(m.collection),
3884
+ method: "PUT",
3885
+ path: DATASTORE_DOC_ENDPOINT(m.collection, m.docId),
3864
3886
  body: { data: m.payload ?? {} },
3865
3887
  requireAuth: true,
3866
- retries: 0,
3888
+ retries: 2,
3867
3889
  headers: tenantHeaders
3868
3890
  });
3869
3891
  } else if (m.op === "set") {
@@ -3879,7 +3901,7 @@ function createRestSyncTransport(config) {
3879
3901
  raw = await httpRequest2(config, {
3880
3902
  method: "PATCH",
3881
3903
  path: DATASTORE_DOC_ENDPOINT(m.collection, m.docId),
3882
- body: { data: m.payload ?? {} },
3904
+ body: { data: m.payload ?? {}, ...m.upsert ? { upsert: true } : {} },
3883
3905
  requireAuth: true,
3884
3906
  retries: 2,
3885
3907
  headers: tenantHeaders
@@ -3902,7 +3924,24 @@ function createRestSyncTransport(config) {
3902
3924
  });
3903
3925
  } catch (err) {
3904
3926
  const msg = err instanceof Error ? err.message : String(err);
3905
- throw new exports.NeetruDbError("db_unavailable", `pushMutations falhou: ${msg}`);
3927
+ const code = err?.code;
3928
+ const status = err?.status;
3929
+ 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;
3930
+ if (isPermanent) {
3931
+ const reason = code === "forbidden" || code === "unauthorized" ? "rejected_permission" : "rejected_validation";
3932
+ results.push({
3933
+ mutationId: m.mutationId,
3934
+ outcome: "rejected",
3935
+ reason,
3936
+ serverVersion: null,
3937
+ serverData: null
3938
+ });
3939
+ continue;
3940
+ }
3941
+ if (results.length === 0) {
3942
+ throw new exports.NeetruDbError("db_unavailable", `pushMutations falhou: ${msg}`);
3943
+ }
3944
+ break;
3906
3945
  }
3907
3946
  }
3908
3947
  return { results };