@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.cjs CHANGED
@@ -1352,7 +1352,71 @@ var MutationQueue = class {
1352
1352
  }
1353
1353
  };
1354
1354
 
1355
+ // src/db/field-value.ts
1356
+ var NEETRU_SENTINEL_KEY = "__neetru__";
1357
+ function serverTimestamp() {
1358
+ return { __neetru__: "serverTimestamp" };
1359
+ }
1360
+ function increment(n) {
1361
+ if (typeof n !== "number" || !Number.isFinite(n)) {
1362
+ throw new TypeError(
1363
+ `increment(n): n deve ser um n\xFAmero finito (recebido: ${String(n)}).`
1364
+ );
1365
+ }
1366
+ return { __neetru__: "increment", operand: n };
1367
+ }
1368
+ function isFieldSentinel(v) {
1369
+ return typeof v === "object" && v !== null && NEETRU_SENTINEL_KEY in v && typeof v[NEETRU_SENTINEL_KEY] === "string";
1370
+ }
1371
+ function isServerTimestampSentinel(v) {
1372
+ return isFieldSentinel(v) && v.__neetru__ === "serverTimestamp";
1373
+ }
1374
+ function isIncrementSentinel(v) {
1375
+ return isFieldSentinel(v) && v.__neetru__ === "increment" && typeof v.operand === "number" && Number.isFinite(v.operand);
1376
+ }
1377
+ function resolveSentinelLocally(value, baseValue) {
1378
+ if (isServerTimestampSentinel(value)) {
1379
+ return Date.now();
1380
+ }
1381
+ if (isIncrementSentinel(value)) {
1382
+ const base = typeof baseValue === "number" && Number.isFinite(baseValue) ? baseValue : 0;
1383
+ return base + value.operand;
1384
+ }
1385
+ return value;
1386
+ }
1387
+ function resolveSentinelsLocally(data, existing) {
1388
+ let touched = false;
1389
+ const out = {};
1390
+ for (const [k, v] of Object.entries(data)) {
1391
+ if (isFieldSentinel(v)) {
1392
+ touched = true;
1393
+ out[k] = resolveSentinelLocally(v, existing?.[k]);
1394
+ } else {
1395
+ out[k] = v;
1396
+ }
1397
+ }
1398
+ return touched ? out : data;
1399
+ }
1400
+ function hasFieldSentinel(data) {
1401
+ for (const v of Object.values(data)) {
1402
+ if (isFieldSentinel(v)) return true;
1403
+ }
1404
+ return false;
1405
+ }
1406
+
1355
1407
  // src/db/offline/sync-engine.ts
1408
+ function hasSentinels(payload) {
1409
+ return payload !== null && hasFieldSentinel(payload);
1410
+ }
1411
+ function sanitizeSentinelPayload(payload) {
1412
+ if (payload === null) return null;
1413
+ if (!hasFieldSentinel(payload)) return payload;
1414
+ const out = {};
1415
+ for (const [k, v] of Object.entries(payload)) {
1416
+ if (!isFieldSentinel(v)) out[k] = v;
1417
+ }
1418
+ return out;
1419
+ }
1356
1420
  var SyncEngine = class {
1357
1421
  _store;
1358
1422
  _queue;
@@ -1540,7 +1604,7 @@ var SyncEngine = class {
1540
1604
  return true;
1541
1605
  }
1542
1606
  /** Atualiza o cache após confirmação de escrita (outcome=confirmed). */
1543
- async _applySyncedDoc(collection, docId, serverVersion, serverTimestamp, mut, busChanges) {
1607
+ async _applySyncedDoc(collection, docId, serverVersion, serverTimestamp2, mut, busChanges) {
1544
1608
  const existing = await this._store.getDoc(collection, docId);
1545
1609
  if (mut.op === "remove") {
1546
1610
  if (existing) {
@@ -1549,7 +1613,7 @@ var SyncEngine = class {
1549
1613
  meta: {
1550
1614
  ...existing.meta,
1551
1615
  serverVersion,
1552
- updatedAtServer: serverTimestamp,
1616
+ updatedAtServer: serverTimestamp2,
1553
1617
  updatedAtLocal: Date.now(),
1554
1618
  state: "synced",
1555
1619
  deleted: true,
@@ -1560,14 +1624,19 @@ var SyncEngine = class {
1560
1624
  }
1561
1625
  return;
1562
1626
  }
1563
- const newData = mut.payload ?? (existing?.data ?? {});
1627
+ const literalPayload = sanitizeSentinelPayload(mut.payload);
1628
+ const newData = literalPayload ?? (existing?.data ?? {});
1564
1629
  const updatedDoc = {
1565
1630
  collection,
1566
1631
  id: docId,
1567
- data: mut.op === "update" ? { ...existing?.data ?? {}, ...newData } : newData,
1632
+ data: mut.op === "update" ? { ...existing?.data ?? {}, ...newData } : (
1633
+ // add/set: se o payload tinha sentinels, o cache otimista (existing.data)
1634
+ // é a fonte de verdade até o pull; senão usa o payload literal.
1635
+ hasSentinels(mut.payload) ? { ...existing?.data ?? {}, ...newData } : newData
1636
+ ),
1568
1637
  meta: {
1569
1638
  serverVersion,
1570
- updatedAtServer: serverTimestamp,
1639
+ updatedAtServer: serverTimestamp2,
1571
1640
  updatedAtLocal: Date.now(),
1572
1641
  state: "synced",
1573
1642
  pendingMutationIds: [],
@@ -2774,10 +2843,12 @@ var DbCollectionRefImpl = class {
2774
2843
  return this._buildListResult(q);
2775
2844
  }
2776
2845
  async add(data) {
2846
+ const rawData = data;
2847
+ const localData = resolveSentinelsLocally(rawData, void 0);
2777
2848
  const mutation = await this._queue.enqueue({
2778
2849
  collection: this._collection,
2779
2850
  op: "add",
2780
- payload: data,
2851
+ payload: rawData,
2781
2852
  baseVersion: null,
2782
2853
  batchId: null
2783
2854
  });
@@ -2785,7 +2856,7 @@ var DbCollectionRefImpl = class {
2785
2856
  await this._store.putDoc({
2786
2857
  collection: this._collection,
2787
2858
  id: docId,
2788
- data,
2859
+ data: localData,
2789
2860
  meta: {
2790
2861
  serverVersion: null,
2791
2862
  updatedAtServer: null,
@@ -2799,25 +2870,27 @@ var DbCollectionRefImpl = class {
2799
2870
  this._bus.emit([{
2800
2871
  type: "added",
2801
2872
  collection: this._collection,
2802
- doc: { id: docId, data }
2873
+ doc: { id: docId, data: localData }
2803
2874
  }]);
2804
2875
  return { ok: true, id: docId };
2805
2876
  }
2806
2877
  async set(id, data) {
2807
2878
  assertValidId(id);
2808
2879
  const existing = await this._store.getDoc(this._collection, id);
2880
+ const rawData = data;
2881
+ const localData = resolveSentinelsLocally(rawData, void 0);
2809
2882
  const mutation = await this._queue.enqueue({
2810
2883
  collection: this._collection,
2811
2884
  docId: id,
2812
2885
  op: "set",
2813
- payload: data,
2886
+ payload: rawData,
2814
2887
  baseVersion: existing?.meta.serverVersion ?? null,
2815
2888
  batchId: null
2816
2889
  });
2817
2890
  await this._store.putDoc({
2818
2891
  collection: this._collection,
2819
2892
  id,
2820
- data,
2893
+ data: localData,
2821
2894
  meta: {
2822
2895
  serverVersion: existing?.meta.serverVersion ?? null,
2823
2896
  updatedAtServer: existing?.meta.updatedAtServer ?? null,
@@ -2831,19 +2904,22 @@ var DbCollectionRefImpl = class {
2831
2904
  this._bus.emit([{
2832
2905
  type: existing && !existing.meta.deleted ? "modified" : "added",
2833
2906
  collection: this._collection,
2834
- doc: { id, data }
2907
+ doc: { id, data: localData }
2835
2908
  }]);
2836
2909
  return { ok: true };
2837
2910
  }
2838
2911
  async update(id, data) {
2839
2912
  assertValidId(id);
2840
2913
  const existing = await this._store.getDoc(this._collection, id);
2841
- const mergedData = existing?.meta.deleted ? { ...data } : { ...existing?.data ?? {}, ...data };
2914
+ const rawData = data;
2915
+ const existingBase = existing?.meta.deleted ? void 0 : existing?.data;
2916
+ const localData = resolveSentinelsLocally(rawData, existingBase);
2917
+ const mergedData = existing?.meta.deleted ? { ...localData } : { ...existing?.data ?? {}, ...localData };
2842
2918
  const mutation = await this._queue.enqueue({
2843
2919
  collection: this._collection,
2844
2920
  docId: id,
2845
2921
  op: "update",
2846
- payload: data,
2922
+ payload: rawData,
2847
2923
  baseVersion: existing?.meta.serverVersion ?? null,
2848
2924
  batchId: null
2849
2925
  });
@@ -2900,6 +2976,7 @@ var DbCollectionRefImpl = class {
2900
2976
  const collection = this._collection;
2901
2977
  if (op.kind === "add") {
2902
2978
  const data = op.data;
2979
+ const localData = resolveSentinelsLocally(data, void 0);
2903
2980
  const mutation = await this._queue.enqueue({
2904
2981
  collection,
2905
2982
  op: "add",
@@ -2911,7 +2988,7 @@ var DbCollectionRefImpl = class {
2911
2988
  await this._store.putDoc({
2912
2989
  collection,
2913
2990
  id: docId,
2914
- data,
2991
+ data: localData,
2915
2992
  meta: {
2916
2993
  serverVersion: null,
2917
2994
  updatedAtServer: null,
@@ -2922,11 +2999,12 @@ var DbCollectionRefImpl = class {
2922
2999
  ownerId: null
2923
3000
  }
2924
3001
  });
2925
- busChanges.push({ type: "added", collection, doc: { id: docId, data } });
3002
+ busChanges.push({ type: "added", collection, doc: { id: docId, data: localData } });
2926
3003
  } else if (op.kind === "set") {
2927
3004
  const id = op.id;
2928
3005
  const data = op.data;
2929
3006
  const existing = await this._store.getDoc(collection, id);
3007
+ const localData = resolveSentinelsLocally(data, void 0);
2930
3008
  const mutation = await this._queue.enqueue({
2931
3009
  collection,
2932
3010
  docId: id,
@@ -2938,7 +3016,7 @@ var DbCollectionRefImpl = class {
2938
3016
  await this._store.putDoc({
2939
3017
  collection,
2940
3018
  id,
2941
- data,
3019
+ data: localData,
2942
3020
  meta: {
2943
3021
  serverVersion: existing?.meta.serverVersion ?? null,
2944
3022
  updatedAtServer: existing?.meta.updatedAtServer ?? null,
@@ -2952,13 +3030,15 @@ var DbCollectionRefImpl = class {
2952
3030
  busChanges.push({
2953
3031
  type: existing && !existing.meta.deleted ? "modified" : "added",
2954
3032
  collection,
2955
- doc: { id, data }
3033
+ doc: { id, data: localData }
2956
3034
  });
2957
3035
  } else if (op.kind === "update") {
2958
3036
  const id = op.id;
2959
3037
  const data = op.data;
2960
3038
  const existing = await this._store.getDoc(collection, id);
2961
- const merged = { ...existing?.data ?? {}, ...data };
3039
+ const existingBase = existing?.meta.deleted ? void 0 : existing?.data;
3040
+ const localData = resolveSentinelsLocally(data, existingBase);
3041
+ const merged = { ...existing?.data ?? {}, ...localData };
2962
3042
  const mutation = await this._queue.enqueue({
2963
3043
  collection,
2964
3044
  docId: id,
@@ -3990,8 +4070,14 @@ function createLazyCollectionRef(name, getDocsPromise) {
3990
4070
  };
3991
4071
  }
3992
4072
 
4073
+ exports.NEETRU_SENTINEL_KEY = NEETRU_SENTINEL_KEY;
3993
4074
  exports.createNeetruDb = createNeetruDb;
3994
4075
  exports.createRestSyncTransport = createRestSyncTransport;
3995
4076
  exports.getWebSocketRealtimeClient = getWebSocketRealtimeClient;
4077
+ exports.increment = increment;
4078
+ exports.isFieldSentinel = isFieldSentinel;
4079
+ exports.isIncrementSentinel = isIncrementSentinel;
4080
+ exports.isServerTimestampSentinel = isServerTimestampSentinel;
4081
+ exports.serverTimestamp = serverTimestamp;
3996
4082
  //# sourceMappingURL=db.cjs.map
3997
4083
  //# sourceMappingURL=db.cjs.map