@neetru/sdk 3.0.1 → 3.1.0

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 (60) hide show
  1. package/CHANGELOG.md +554 -492
  2. package/dist/auth.cjs +84 -15
  3. package/dist/auth.cjs.map +1 -1
  4. package/dist/auth.d.cts +1 -2
  5. package/dist/auth.d.ts +1 -2
  6. package/dist/auth.mjs +84 -15
  7. package/dist/auth.mjs.map +1 -1
  8. package/dist/catalog.d.cts +1 -2
  9. package/dist/catalog.d.ts +1 -2
  10. package/dist/checkout.d.cts +1 -2
  11. package/dist/checkout.d.ts +1 -2
  12. package/dist/db-react.cjs +15 -5
  13. package/dist/db-react.cjs.map +1 -1
  14. package/dist/db-react.d.cts +35 -13
  15. package/dist/db-react.d.ts +35 -13
  16. package/dist/db-react.mjs +15 -5
  17. package/dist/db-react.mjs.map +1 -1
  18. package/dist/db.cjs +104 -18
  19. package/dist/db.cjs.map +1 -1
  20. package/dist/db.d.cts +1 -2
  21. package/dist/db.d.ts +1 -2
  22. package/dist/db.mjs +99 -19
  23. package/dist/db.mjs.map +1 -1
  24. package/dist/entitlements.d.cts +1 -2
  25. package/dist/entitlements.d.ts +1 -2
  26. package/dist/firestore-compat.cjs +399 -0
  27. package/dist/firestore-compat.cjs.map +1 -0
  28. package/dist/firestore-compat.d.cts +294 -0
  29. package/dist/firestore-compat.d.ts +294 -0
  30. package/dist/firestore-compat.mjs +371 -0
  31. package/dist/firestore-compat.mjs.map +1 -0
  32. package/dist/index.cjs +105 -19
  33. package/dist/index.cjs.map +1 -1
  34. package/dist/index.d.cts +2 -3
  35. package/dist/index.d.ts +2 -3
  36. package/dist/index.mjs +100 -20
  37. package/dist/index.mjs.map +1 -1
  38. package/dist/mocks.d.cts +1 -2
  39. package/dist/mocks.d.ts +1 -2
  40. package/dist/notifications.d.cts +1 -2
  41. package/dist/notifications.d.ts +1 -2
  42. package/dist/react.cjs +267 -0
  43. package/dist/react.cjs.map +1 -1
  44. package/dist/react.d.cts +117 -3
  45. package/dist/react.d.ts +117 -3
  46. package/dist/react.mjs +265 -1
  47. package/dist/react.mjs.map +1 -1
  48. package/dist/support.d.cts +1 -2
  49. package/dist/support.d.ts +1 -2
  50. package/dist/telemetry.d.cts +1 -2
  51. package/dist/telemetry.d.ts +1 -2
  52. package/dist/{types-DALIhcbq.d.ts → types-BRv8wBxX.d.ts} +581 -2
  53. package/dist/{types-Lfd3LiAF.d.cts → types-nwErcRX8.d.cts} +581 -2
  54. package/dist/usage.d.cts +1 -2
  55. package/dist/usage.d.ts +1 -2
  56. package/dist/webhooks.d.cts +1 -2
  57. package/dist/webhooks.d.ts +1 -2
  58. package/package.json +156 -151
  59. package/dist/collection-ref-DqAAhuhX.d.cts +0 -472
  60. package/dist/collection-ref-DqAAhuhX.d.ts +0 -472
package/dist/db.d.cts CHANGED
@@ -1,4 +1,3 @@
1
- export { C as ConflictRecord, a as CreateOfflineDocumentsOptions, D as DbBatchOp, b as DbChangeType, c as DbCollectionRef, d as DbDoc, e as DbDocRef, f as DbGetResult, g as DbListResult, h as DbQuery, i as DbWhereFilter, N as NeetruDbDocuments, R as RealtimeTransport, S as SyncState } from './collection-ref-DqAAhuhX.cjs';
2
- export { k as DbSqlLease, p as NeetruDb, q as NeetruDbEngine, r as NeetruDbError, s as NeetruDbErrorCode, t as NeetruDbOptions, u as NeetruDbTransport, w as NeetruSqlClient, K as SqlOptions, a7 as createNeetruDb, a9 as createRestSyncTransport, ab as getWebSocketRealtimeClient } from './types-Lfd3LiAF.cjs';
1
+ export { i as ConflictRecord, j as CreateOfflineDocumentsOptions, l as DbBatchOp, m as DbChangeType, n as DbCollectionRef, o as DbDoc, p as DbDocRef, q as DbGetResult, r as DbListResult, t as DbQuery, u as DbSqlLease, w as DbWhereFilter, F as FieldSentinel, I as IncrementSentinel, N as NEETRU_SENTINEL_KEY, G as NeetruDb, H as NeetruDbDocuments, J as NeetruDbEngine, K as NeetruDbError, O as NeetruDbErrorCode, P as NeetruDbOptions, Q as NeetruDbTransport, S as NeetruSqlClient, $ as RealtimeTransport, a3 as ServerTimestampSentinel, a5 as SqlOptions, aa as SyncState, ap as WithFieldSentinels, ar as createNeetruDb, at as createRestSyncTransport, av as getWebSocketRealtimeClient, aw as increment, ax as isFieldSentinel, ay as isIncrementSentinel, az as isServerTimestampSentinel, aA as serverTimestamp } from './types-nwErcRX8.cjs';
3
2
  import 'drizzle-orm/node-postgres';
4
3
  import './errors.cjs';
package/dist/db.d.ts CHANGED
@@ -1,4 +1,3 @@
1
- export { C as ConflictRecord, a as CreateOfflineDocumentsOptions, D as DbBatchOp, b as DbChangeType, c as DbCollectionRef, d as DbDoc, e as DbDocRef, f as DbGetResult, g as DbListResult, h as DbQuery, i as DbWhereFilter, N as NeetruDbDocuments, R as RealtimeTransport, S as SyncState } from './collection-ref-DqAAhuhX.js';
2
- export { k as DbSqlLease, p as NeetruDb, q as NeetruDbEngine, r as NeetruDbError, s as NeetruDbErrorCode, t as NeetruDbOptions, u as NeetruDbTransport, w as NeetruSqlClient, K as SqlOptions, a7 as createNeetruDb, a9 as createRestSyncTransport, ab as getWebSocketRealtimeClient } from './types-DALIhcbq.js';
1
+ export { i as ConflictRecord, j as CreateOfflineDocumentsOptions, l as DbBatchOp, m as DbChangeType, n as DbCollectionRef, o as DbDoc, p as DbDocRef, q as DbGetResult, r as DbListResult, t as DbQuery, u as DbSqlLease, w as DbWhereFilter, F as FieldSentinel, I as IncrementSentinel, N as NEETRU_SENTINEL_KEY, G as NeetruDb, H as NeetruDbDocuments, J as NeetruDbEngine, K as NeetruDbError, O as NeetruDbErrorCode, P as NeetruDbOptions, Q as NeetruDbTransport, S as NeetruSqlClient, $ as RealtimeTransport, a3 as ServerTimestampSentinel, a5 as SqlOptions, aa as SyncState, ap as WithFieldSentinels, ar as createNeetruDb, at as createRestSyncTransport, av as getWebSocketRealtimeClient, aw as increment, ax as isFieldSentinel, ay as isIncrementSentinel, az as isServerTimestampSentinel, aA as serverTimestamp } from './types-BRv8wBxX.js';
3
2
  import 'drizzle-orm/node-postgres';
4
3
  import './errors.js';
package/dist/db.mjs CHANGED
@@ -1350,7 +1350,71 @@ var MutationQueue = class {
1350
1350
  }
1351
1351
  };
1352
1352
 
1353
+ // src/db/field-value.ts
1354
+ var NEETRU_SENTINEL_KEY = "__neetru__";
1355
+ function serverTimestamp() {
1356
+ return { __neetru__: "serverTimestamp" };
1357
+ }
1358
+ function increment(n) {
1359
+ if (typeof n !== "number" || !Number.isFinite(n)) {
1360
+ throw new TypeError(
1361
+ `increment(n): n deve ser um n\xFAmero finito (recebido: ${String(n)}).`
1362
+ );
1363
+ }
1364
+ return { __neetru__: "increment", operand: n };
1365
+ }
1366
+ function isFieldSentinel(v) {
1367
+ return typeof v === "object" && v !== null && NEETRU_SENTINEL_KEY in v && typeof v[NEETRU_SENTINEL_KEY] === "string";
1368
+ }
1369
+ function isServerTimestampSentinel(v) {
1370
+ return isFieldSentinel(v) && v.__neetru__ === "serverTimestamp";
1371
+ }
1372
+ function isIncrementSentinel(v) {
1373
+ return isFieldSentinel(v) && v.__neetru__ === "increment" && typeof v.operand === "number" && Number.isFinite(v.operand);
1374
+ }
1375
+ function resolveSentinelLocally(value, baseValue) {
1376
+ if (isServerTimestampSentinel(value)) {
1377
+ return Date.now();
1378
+ }
1379
+ if (isIncrementSentinel(value)) {
1380
+ const base = typeof baseValue === "number" && Number.isFinite(baseValue) ? baseValue : 0;
1381
+ return base + value.operand;
1382
+ }
1383
+ return value;
1384
+ }
1385
+ function resolveSentinelsLocally(data, existing) {
1386
+ let touched = false;
1387
+ const out = {};
1388
+ for (const [k, v] of Object.entries(data)) {
1389
+ if (isFieldSentinel(v)) {
1390
+ touched = true;
1391
+ out[k] = resolveSentinelLocally(v, existing?.[k]);
1392
+ } else {
1393
+ out[k] = v;
1394
+ }
1395
+ }
1396
+ return touched ? out : data;
1397
+ }
1398
+ function hasFieldSentinel(data) {
1399
+ for (const v of Object.values(data)) {
1400
+ if (isFieldSentinel(v)) return true;
1401
+ }
1402
+ return false;
1403
+ }
1404
+
1353
1405
  // src/db/offline/sync-engine.ts
1406
+ function hasSentinels(payload) {
1407
+ return payload !== null && hasFieldSentinel(payload);
1408
+ }
1409
+ function sanitizeSentinelPayload(payload) {
1410
+ if (payload === null) return null;
1411
+ if (!hasFieldSentinel(payload)) return payload;
1412
+ const out = {};
1413
+ for (const [k, v] of Object.entries(payload)) {
1414
+ if (!isFieldSentinel(v)) out[k] = v;
1415
+ }
1416
+ return out;
1417
+ }
1354
1418
  var SyncEngine = class {
1355
1419
  _store;
1356
1420
  _queue;
@@ -1538,7 +1602,7 @@ var SyncEngine = class {
1538
1602
  return true;
1539
1603
  }
1540
1604
  /** Atualiza o cache após confirmação de escrita (outcome=confirmed). */
1541
- async _applySyncedDoc(collection, docId, serverVersion, serverTimestamp, mut, busChanges) {
1605
+ async _applySyncedDoc(collection, docId, serverVersion, serverTimestamp2, mut, busChanges) {
1542
1606
  const existing = await this._store.getDoc(collection, docId);
1543
1607
  if (mut.op === "remove") {
1544
1608
  if (existing) {
@@ -1547,7 +1611,7 @@ var SyncEngine = class {
1547
1611
  meta: {
1548
1612
  ...existing.meta,
1549
1613
  serverVersion,
1550
- updatedAtServer: serverTimestamp,
1614
+ updatedAtServer: serverTimestamp2,
1551
1615
  updatedAtLocal: Date.now(),
1552
1616
  state: "synced",
1553
1617
  deleted: true,
@@ -1558,14 +1622,19 @@ var SyncEngine = class {
1558
1622
  }
1559
1623
  return;
1560
1624
  }
1561
- const newData = mut.payload ?? (existing?.data ?? {});
1625
+ const literalPayload = sanitizeSentinelPayload(mut.payload);
1626
+ const newData = literalPayload ?? (existing?.data ?? {});
1562
1627
  const updatedDoc = {
1563
1628
  collection,
1564
1629
  id: docId,
1565
- data: mut.op === "update" ? { ...existing?.data ?? {}, ...newData } : newData,
1630
+ data: mut.op === "update" ? { ...existing?.data ?? {}, ...newData } : (
1631
+ // add/set: se o payload tinha sentinels, o cache otimista (existing.data)
1632
+ // é a fonte de verdade até o pull; senão usa o payload literal.
1633
+ hasSentinels(mut.payload) ? { ...existing?.data ?? {}, ...newData } : newData
1634
+ ),
1566
1635
  meta: {
1567
1636
  serverVersion,
1568
- updatedAtServer: serverTimestamp,
1637
+ updatedAtServer: serverTimestamp2,
1569
1638
  updatedAtLocal: Date.now(),
1570
1639
  state: "synced",
1571
1640
  pendingMutationIds: [],
@@ -2772,10 +2841,12 @@ var DbCollectionRefImpl = class {
2772
2841
  return this._buildListResult(q);
2773
2842
  }
2774
2843
  async add(data) {
2844
+ const rawData = data;
2845
+ const localData = resolveSentinelsLocally(rawData, void 0);
2775
2846
  const mutation = await this._queue.enqueue({
2776
2847
  collection: this._collection,
2777
2848
  op: "add",
2778
- payload: data,
2849
+ payload: rawData,
2779
2850
  baseVersion: null,
2780
2851
  batchId: null
2781
2852
  });
@@ -2783,7 +2854,7 @@ var DbCollectionRefImpl = class {
2783
2854
  await this._store.putDoc({
2784
2855
  collection: this._collection,
2785
2856
  id: docId,
2786
- data,
2857
+ data: localData,
2787
2858
  meta: {
2788
2859
  serverVersion: null,
2789
2860
  updatedAtServer: null,
@@ -2797,25 +2868,27 @@ var DbCollectionRefImpl = class {
2797
2868
  this._bus.emit([{
2798
2869
  type: "added",
2799
2870
  collection: this._collection,
2800
- doc: { id: docId, data }
2871
+ doc: { id: docId, data: localData }
2801
2872
  }]);
2802
2873
  return { ok: true, id: docId };
2803
2874
  }
2804
2875
  async set(id, data) {
2805
2876
  assertValidId(id);
2806
2877
  const existing = await this._store.getDoc(this._collection, id);
2878
+ const rawData = data;
2879
+ const localData = resolveSentinelsLocally(rawData, void 0);
2807
2880
  const mutation = await this._queue.enqueue({
2808
2881
  collection: this._collection,
2809
2882
  docId: id,
2810
2883
  op: "set",
2811
- payload: data,
2884
+ payload: rawData,
2812
2885
  baseVersion: existing?.meta.serverVersion ?? null,
2813
2886
  batchId: null
2814
2887
  });
2815
2888
  await this._store.putDoc({
2816
2889
  collection: this._collection,
2817
2890
  id,
2818
- data,
2891
+ data: localData,
2819
2892
  meta: {
2820
2893
  serverVersion: existing?.meta.serverVersion ?? null,
2821
2894
  updatedAtServer: existing?.meta.updatedAtServer ?? null,
@@ -2829,19 +2902,22 @@ var DbCollectionRefImpl = class {
2829
2902
  this._bus.emit([{
2830
2903
  type: existing && !existing.meta.deleted ? "modified" : "added",
2831
2904
  collection: this._collection,
2832
- doc: { id, data }
2905
+ doc: { id, data: localData }
2833
2906
  }]);
2834
2907
  return { ok: true };
2835
2908
  }
2836
2909
  async update(id, data) {
2837
2910
  assertValidId(id);
2838
2911
  const existing = await this._store.getDoc(this._collection, id);
2839
- const mergedData = existing?.meta.deleted ? { ...data } : { ...existing?.data ?? {}, ...data };
2912
+ const rawData = data;
2913
+ const existingBase = existing?.meta.deleted ? void 0 : existing?.data;
2914
+ const localData = resolveSentinelsLocally(rawData, existingBase);
2915
+ const mergedData = existing?.meta.deleted ? { ...localData } : { ...existing?.data ?? {}, ...localData };
2840
2916
  const mutation = await this._queue.enqueue({
2841
2917
  collection: this._collection,
2842
2918
  docId: id,
2843
2919
  op: "update",
2844
- payload: data,
2920
+ payload: rawData,
2845
2921
  baseVersion: existing?.meta.serverVersion ?? null,
2846
2922
  batchId: null
2847
2923
  });
@@ -2898,6 +2974,7 @@ var DbCollectionRefImpl = class {
2898
2974
  const collection = this._collection;
2899
2975
  if (op.kind === "add") {
2900
2976
  const data = op.data;
2977
+ const localData = resolveSentinelsLocally(data, void 0);
2901
2978
  const mutation = await this._queue.enqueue({
2902
2979
  collection,
2903
2980
  op: "add",
@@ -2909,7 +2986,7 @@ var DbCollectionRefImpl = class {
2909
2986
  await this._store.putDoc({
2910
2987
  collection,
2911
2988
  id: docId,
2912
- data,
2989
+ data: localData,
2913
2990
  meta: {
2914
2991
  serverVersion: null,
2915
2992
  updatedAtServer: null,
@@ -2920,11 +2997,12 @@ var DbCollectionRefImpl = class {
2920
2997
  ownerId: null
2921
2998
  }
2922
2999
  });
2923
- busChanges.push({ type: "added", collection, doc: { id: docId, data } });
3000
+ busChanges.push({ type: "added", collection, doc: { id: docId, data: localData } });
2924
3001
  } else if (op.kind === "set") {
2925
3002
  const id = op.id;
2926
3003
  const data = op.data;
2927
3004
  const existing = await this._store.getDoc(collection, id);
3005
+ const localData = resolveSentinelsLocally(data, void 0);
2928
3006
  const mutation = await this._queue.enqueue({
2929
3007
  collection,
2930
3008
  docId: id,
@@ -2936,7 +3014,7 @@ var DbCollectionRefImpl = class {
2936
3014
  await this._store.putDoc({
2937
3015
  collection,
2938
3016
  id,
2939
- data,
3017
+ data: localData,
2940
3018
  meta: {
2941
3019
  serverVersion: existing?.meta.serverVersion ?? null,
2942
3020
  updatedAtServer: existing?.meta.updatedAtServer ?? null,
@@ -2950,13 +3028,15 @@ var DbCollectionRefImpl = class {
2950
3028
  busChanges.push({
2951
3029
  type: existing && !existing.meta.deleted ? "modified" : "added",
2952
3030
  collection,
2953
- doc: { id, data }
3031
+ doc: { id, data: localData }
2954
3032
  });
2955
3033
  } else if (op.kind === "update") {
2956
3034
  const id = op.id;
2957
3035
  const data = op.data;
2958
3036
  const existing = await this._store.getDoc(collection, id);
2959
- const merged = { ...existing?.data ?? {}, ...data };
3037
+ const existingBase = existing?.meta.deleted ? void 0 : existing?.data;
3038
+ const localData = resolveSentinelsLocally(data, existingBase);
3039
+ const merged = { ...existing?.data ?? {}, ...localData };
2960
3040
  const mutation = await this._queue.enqueue({
2961
3041
  collection,
2962
3042
  docId: id,
@@ -3988,6 +4068,6 @@ function createLazyCollectionRef(name, getDocsPromise) {
3988
4068
  };
3989
4069
  }
3990
4070
 
3991
- export { NeetruDbError, createNeetruDb, createRestSyncTransport, getWebSocketRealtimeClient };
4071
+ export { NEETRU_SENTINEL_KEY, NeetruDbError, createNeetruDb, createRestSyncTransport, getWebSocketRealtimeClient, increment, isFieldSentinel, isIncrementSentinel, isServerTimestampSentinel, serverTimestamp };
3992
4072
  //# sourceMappingURL=db.mjs.map
3993
4073
  //# sourceMappingURL=db.mjs.map