@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/index.cjs CHANGED
@@ -2043,7 +2043,71 @@ var MutationQueue = class {
2043
2043
  }
2044
2044
  };
2045
2045
 
2046
+ // src/db/field-value.ts
2047
+ var NEETRU_SENTINEL_KEY = "__neetru__";
2048
+ function serverTimestamp() {
2049
+ return { __neetru__: "serverTimestamp" };
2050
+ }
2051
+ function increment(n) {
2052
+ if (typeof n !== "number" || !Number.isFinite(n)) {
2053
+ throw new TypeError(
2054
+ `increment(n): n deve ser um n\xFAmero finito (recebido: ${String(n)}).`
2055
+ );
2056
+ }
2057
+ return { __neetru__: "increment", operand: n };
2058
+ }
2059
+ function isFieldSentinel(v) {
2060
+ return typeof v === "object" && v !== null && NEETRU_SENTINEL_KEY in v && typeof v[NEETRU_SENTINEL_KEY] === "string";
2061
+ }
2062
+ function isServerTimestampSentinel(v) {
2063
+ return isFieldSentinel(v) && v.__neetru__ === "serverTimestamp";
2064
+ }
2065
+ function isIncrementSentinel(v) {
2066
+ return isFieldSentinel(v) && v.__neetru__ === "increment" && typeof v.operand === "number" && Number.isFinite(v.operand);
2067
+ }
2068
+ function resolveSentinelLocally(value, baseValue) {
2069
+ if (isServerTimestampSentinel(value)) {
2070
+ return Date.now();
2071
+ }
2072
+ if (isIncrementSentinel(value)) {
2073
+ const base = typeof baseValue === "number" && Number.isFinite(baseValue) ? baseValue : 0;
2074
+ return base + value.operand;
2075
+ }
2076
+ return value;
2077
+ }
2078
+ function resolveSentinelsLocally(data, existing) {
2079
+ let touched = false;
2080
+ const out = {};
2081
+ for (const [k, v] of Object.entries(data)) {
2082
+ if (isFieldSentinel(v)) {
2083
+ touched = true;
2084
+ out[k] = resolveSentinelLocally(v, existing?.[k]);
2085
+ } else {
2086
+ out[k] = v;
2087
+ }
2088
+ }
2089
+ return touched ? out : data;
2090
+ }
2091
+ function hasFieldSentinel(data) {
2092
+ for (const v of Object.values(data)) {
2093
+ if (isFieldSentinel(v)) return true;
2094
+ }
2095
+ return false;
2096
+ }
2097
+
2046
2098
  // src/db/offline/sync-engine.ts
2099
+ function hasSentinels(payload) {
2100
+ return payload !== null && hasFieldSentinel(payload);
2101
+ }
2102
+ function sanitizeSentinelPayload(payload) {
2103
+ if (payload === null) return null;
2104
+ if (!hasFieldSentinel(payload)) return payload;
2105
+ const out = {};
2106
+ for (const [k, v] of Object.entries(payload)) {
2107
+ if (!isFieldSentinel(v)) out[k] = v;
2108
+ }
2109
+ return out;
2110
+ }
2047
2111
  var SyncEngine = class {
2048
2112
  _store;
2049
2113
  _queue;
@@ -2231,7 +2295,7 @@ var SyncEngine = class {
2231
2295
  return true;
2232
2296
  }
2233
2297
  /** Atualiza o cache após confirmação de escrita (outcome=confirmed). */
2234
- async _applySyncedDoc(collection, docId, serverVersion, serverTimestamp, mut, busChanges) {
2298
+ async _applySyncedDoc(collection, docId, serverVersion, serverTimestamp2, mut, busChanges) {
2235
2299
  const existing = await this._store.getDoc(collection, docId);
2236
2300
  if (mut.op === "remove") {
2237
2301
  if (existing) {
@@ -2240,7 +2304,7 @@ var SyncEngine = class {
2240
2304
  meta: {
2241
2305
  ...existing.meta,
2242
2306
  serverVersion,
2243
- updatedAtServer: serverTimestamp,
2307
+ updatedAtServer: serverTimestamp2,
2244
2308
  updatedAtLocal: Date.now(),
2245
2309
  state: "synced",
2246
2310
  deleted: true,
@@ -2251,14 +2315,19 @@ var SyncEngine = class {
2251
2315
  }
2252
2316
  return;
2253
2317
  }
2254
- const newData = mut.payload ?? (existing?.data ?? {});
2318
+ const literalPayload = sanitizeSentinelPayload(mut.payload);
2319
+ const newData = literalPayload ?? (existing?.data ?? {});
2255
2320
  const updatedDoc = {
2256
2321
  collection,
2257
2322
  id: docId,
2258
- data: mut.op === "update" ? { ...existing?.data ?? {}, ...newData } : newData,
2323
+ data: mut.op === "update" ? { ...existing?.data ?? {}, ...newData } : (
2324
+ // add/set: se o payload tinha sentinels, o cache otimista (existing.data)
2325
+ // é a fonte de verdade até o pull; senão usa o payload literal.
2326
+ hasSentinels(mut.payload) ? { ...existing?.data ?? {}, ...newData } : newData
2327
+ ),
2259
2328
  meta: {
2260
2329
  serverVersion,
2261
- updatedAtServer: serverTimestamp,
2330
+ updatedAtServer: serverTimestamp2,
2262
2331
  updatedAtLocal: Date.now(),
2263
2332
  state: "synced",
2264
2333
  pendingMutationIds: [],
@@ -3465,10 +3534,12 @@ var DbCollectionRefImpl = class {
3465
3534
  return this._buildListResult(q);
3466
3535
  }
3467
3536
  async add(data) {
3537
+ const rawData = data;
3538
+ const localData = resolveSentinelsLocally(rawData, void 0);
3468
3539
  const mutation = await this._queue.enqueue({
3469
3540
  collection: this._collection,
3470
3541
  op: "add",
3471
- payload: data,
3542
+ payload: rawData,
3472
3543
  baseVersion: null,
3473
3544
  batchId: null
3474
3545
  });
@@ -3476,7 +3547,7 @@ var DbCollectionRefImpl = class {
3476
3547
  await this._store.putDoc({
3477
3548
  collection: this._collection,
3478
3549
  id: docId,
3479
- data,
3550
+ data: localData,
3480
3551
  meta: {
3481
3552
  serverVersion: null,
3482
3553
  updatedAtServer: null,
@@ -3490,25 +3561,27 @@ var DbCollectionRefImpl = class {
3490
3561
  this._bus.emit([{
3491
3562
  type: "added",
3492
3563
  collection: this._collection,
3493
- doc: { id: docId, data }
3564
+ doc: { id: docId, data: localData }
3494
3565
  }]);
3495
3566
  return { ok: true, id: docId };
3496
3567
  }
3497
3568
  async set(id, data) {
3498
3569
  assertValidId(id);
3499
3570
  const existing = await this._store.getDoc(this._collection, id);
3571
+ const rawData = data;
3572
+ const localData = resolveSentinelsLocally(rawData, void 0);
3500
3573
  const mutation = await this._queue.enqueue({
3501
3574
  collection: this._collection,
3502
3575
  docId: id,
3503
3576
  op: "set",
3504
- payload: data,
3577
+ payload: rawData,
3505
3578
  baseVersion: existing?.meta.serverVersion ?? null,
3506
3579
  batchId: null
3507
3580
  });
3508
3581
  await this._store.putDoc({
3509
3582
  collection: this._collection,
3510
3583
  id,
3511
- data,
3584
+ data: localData,
3512
3585
  meta: {
3513
3586
  serverVersion: existing?.meta.serverVersion ?? null,
3514
3587
  updatedAtServer: existing?.meta.updatedAtServer ?? null,
@@ -3522,19 +3595,22 @@ var DbCollectionRefImpl = class {
3522
3595
  this._bus.emit([{
3523
3596
  type: existing && !existing.meta.deleted ? "modified" : "added",
3524
3597
  collection: this._collection,
3525
- doc: { id, data }
3598
+ doc: { id, data: localData }
3526
3599
  }]);
3527
3600
  return { ok: true };
3528
3601
  }
3529
3602
  async update(id, data) {
3530
3603
  assertValidId(id);
3531
3604
  const existing = await this._store.getDoc(this._collection, id);
3532
- const mergedData = existing?.meta.deleted ? { ...data } : { ...existing?.data ?? {}, ...data };
3605
+ const rawData = data;
3606
+ const existingBase = existing?.meta.deleted ? void 0 : existing?.data;
3607
+ const localData = resolveSentinelsLocally(rawData, existingBase);
3608
+ const mergedData = existing?.meta.deleted ? { ...localData } : { ...existing?.data ?? {}, ...localData };
3533
3609
  const mutation = await this._queue.enqueue({
3534
3610
  collection: this._collection,
3535
3611
  docId: id,
3536
3612
  op: "update",
3537
- payload: data,
3613
+ payload: rawData,
3538
3614
  baseVersion: existing?.meta.serverVersion ?? null,
3539
3615
  batchId: null
3540
3616
  });
@@ -3591,6 +3667,7 @@ var DbCollectionRefImpl = class {
3591
3667
  const collection = this._collection;
3592
3668
  if (op.kind === "add") {
3593
3669
  const data = op.data;
3670
+ const localData = resolveSentinelsLocally(data, void 0);
3594
3671
  const mutation = await this._queue.enqueue({
3595
3672
  collection,
3596
3673
  op: "add",
@@ -3602,7 +3679,7 @@ var DbCollectionRefImpl = class {
3602
3679
  await this._store.putDoc({
3603
3680
  collection,
3604
3681
  id: docId,
3605
- data,
3682
+ data: localData,
3606
3683
  meta: {
3607
3684
  serverVersion: null,
3608
3685
  updatedAtServer: null,
@@ -3613,11 +3690,12 @@ var DbCollectionRefImpl = class {
3613
3690
  ownerId: null
3614
3691
  }
3615
3692
  });
3616
- busChanges.push({ type: "added", collection, doc: { id: docId, data } });
3693
+ busChanges.push({ type: "added", collection, doc: { id: docId, data: localData } });
3617
3694
  } else if (op.kind === "set") {
3618
3695
  const id = op.id;
3619
3696
  const data = op.data;
3620
3697
  const existing = await this._store.getDoc(collection, id);
3698
+ const localData = resolveSentinelsLocally(data, void 0);
3621
3699
  const mutation = await this._queue.enqueue({
3622
3700
  collection,
3623
3701
  docId: id,
@@ -3629,7 +3707,7 @@ var DbCollectionRefImpl = class {
3629
3707
  await this._store.putDoc({
3630
3708
  collection,
3631
3709
  id,
3632
- data,
3710
+ data: localData,
3633
3711
  meta: {
3634
3712
  serverVersion: existing?.meta.serverVersion ?? null,
3635
3713
  updatedAtServer: existing?.meta.updatedAtServer ?? null,
@@ -3643,13 +3721,15 @@ var DbCollectionRefImpl = class {
3643
3721
  busChanges.push({
3644
3722
  type: existing && !existing.meta.deleted ? "modified" : "added",
3645
3723
  collection,
3646
- doc: { id, data }
3724
+ doc: { id, data: localData }
3647
3725
  });
3648
3726
  } else if (op.kind === "update") {
3649
3727
  const id = op.id;
3650
3728
  const data = op.data;
3651
3729
  const existing = await this._store.getDoc(collection, id);
3652
- const merged = { ...existing?.data ?? {}, ...data };
3730
+ const existingBase = existing?.meta.deleted ? void 0 : existing?.data;
3731
+ const localData = resolveSentinelsLocally(data, existingBase);
3732
+ const merged = { ...existing?.data ?? {}, ...localData };
3653
3733
  const mutation = await this._queue.enqueue({
3654
3734
  collection,
3655
3735
  docId: id,
@@ -6083,7 +6163,7 @@ function createNeetruClient(config = {}) {
6083
6163
  // src/index.ts
6084
6164
  init_errors();
6085
6165
  init_db_errors();
6086
- var VERSION = "3.0.1";
6166
+ var VERSION = "3.1.0";
6087
6167
 
6088
6168
  exports.DEFAULT_BASE_URL = DEFAULT_BASE_URL;
6089
6169
  exports.DEV_FIXTURE_USER = DEV_FIXTURE_USER;
@@ -6095,12 +6175,18 @@ exports.MockNotifications = MockNotifications;
6095
6175
  exports.MockSupport = MockSupport;
6096
6176
  exports.MockUsage = MockUsage;
6097
6177
  exports.MockWebhooks = MockWebhooks;
6178
+ exports.NEETRU_SENTINEL_KEY = NEETRU_SENTINEL_KEY;
6098
6179
  exports.VERSION = VERSION;
6099
6180
  exports.createCheckoutNamespace = createCheckoutNamespace;
6100
6181
  exports.createNeetruClient = createNeetruClient;
6101
6182
  exports.createNeetruDb = createNeetruDb;
6102
6183
  exports.createNotificationsNamespace = createNotificationsNamespace;
6103
6184
  exports.createWebhooksNamespace = createWebhooksNamespace;
6185
+ exports.increment = increment;
6186
+ exports.isFieldSentinel = isFieldSentinel;
6187
+ exports.isIncrementSentinel = isIncrementSentinel;
6188
+ exports.isServerTimestampSentinel = isServerTimestampSentinel;
6189
+ exports.serverTimestamp = serverTimestamp;
6104
6190
  exports.verifyWebhookSignature = verifyWebhookSignature;
6105
6191
  //# sourceMappingURL=index.cjs.map
6106
6192
  //# sourceMappingURL=index.cjs.map