kaafil-react-uikit 0.2.0 → 0.3.1

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 (35) hide show
  1. package/dist/admin/index.cjs +73 -73
  2. package/dist/admin/index.js +3 -3
  3. package/dist/{chunk-6WV5VYT2.cjs → chunk-6TI6YQPE.cjs} +171 -7
  4. package/dist/chunk-6TI6YQPE.cjs.map +1 -0
  5. package/dist/{chunk-RG4YDSCN.cjs → chunk-BBC5EX5O.cjs} +4 -4
  6. package/dist/{chunk-RG4YDSCN.cjs.map → chunk-BBC5EX5O.cjs.map} +1 -1
  7. package/dist/{chunk-7UFX3Y2U.cjs → chunk-ECCQW5LN.cjs} +5 -2
  8. package/dist/chunk-ECCQW5LN.cjs.map +1 -0
  9. package/dist/{chunk-OZJ74DVQ.cjs → chunk-HACH2NUM.cjs} +3 -3
  10. package/dist/chunk-HACH2NUM.cjs.map +1 -0
  11. package/dist/{chunk-HTIY33UH.cjs → chunk-IU2UM5JP.cjs} +21 -21
  12. package/dist/{chunk-HTIY33UH.cjs.map → chunk-IU2UM5JP.cjs.map} +1 -1
  13. package/dist/{chunk-RSC2ZJUP.js → chunk-JHMN6Q5R.js} +172 -8
  14. package/dist/chunk-JHMN6Q5R.js.map +1 -0
  15. package/dist/{chunk-SIAPCJ7G.js → chunk-RO2RNHQP.js} +4 -4
  16. package/dist/{chunk-SIAPCJ7G.js.map → chunk-RO2RNHQP.js.map} +1 -1
  17. package/dist/{chunk-7ISKFGLW.js → chunk-RWLO6IFX.js} +3 -3
  18. package/dist/chunk-RWLO6IFX.js.map +1 -0
  19. package/dist/{chunk-L3QEMEFM.js → chunk-VLP323AD.js} +5 -2
  20. package/dist/chunk-VLP323AD.js.map +1 -0
  21. package/dist/{chunk-LJJMNZ7B.js → chunk-YU2242AR.js} +3 -3
  22. package/dist/{chunk-LJJMNZ7B.js.map → chunk-YU2242AR.js.map} +1 -1
  23. package/dist/core/index.cjs +56 -56
  24. package/dist/core/index.js +7 -7
  25. package/dist/manager/index.cjs +48 -48
  26. package/dist/manager/index.js +2 -2
  27. package/dist/traveller/index.cjs +4 -4
  28. package/dist/traveller/index.js +2 -2
  29. package/package.json +2 -2
  30. package/dist/chunk-6WV5VYT2.cjs.map +0 -1
  31. package/dist/chunk-7ISKFGLW.js.map +0 -1
  32. package/dist/chunk-7UFX3Y2U.cjs.map +0 -1
  33. package/dist/chunk-L3QEMEFM.js.map +0 -1
  34. package/dist/chunk-OZJ74DVQ.cjs.map +0 -1
  35. package/dist/chunk-RSC2ZJUP.js.map +0 -1
@@ -1,5 +1,5 @@
1
1
  import { OfflineEngineContext, KaafilClientContext, useCapabilityRows, UNKNOWN_CAPABILITY_TRIPLE, deriveCapabilityTriple, darkReasonFor, useKaafilClient, useOfflineMutation, usePersona, isDevelopment, useOfflineEvent } from './chunk-A4Z2YBEF.js';
2
- import { UnsatisfiableSchemeError, isKaafilError, SyncOpMethod } from 'kaafil-js/client';
2
+ import { UnsatisfiableSchemeError, isKaafilError, SyncOpMethod, normalizeDateTimeInput } from 'kaafil-js/client';
3
3
  export { FALLBACK_GLYPH, SHADES_PER_FAMILY, TONE_FAMILIES, parseRoomingTone, roomingHeuristicSeverity } from 'kaafil-js/client';
4
4
  import { useContext, useState, useRef, useCallback, useEffect } from 'react';
5
5
 
@@ -176,6 +176,51 @@ function createDomainHook(moduleKey, build) {
176
176
  }
177
177
 
178
178
  // src/core/hooks/useChecklists.ts
179
+ function optimisticChecklistItem(input, sections, fetchedAt) {
180
+ return {
181
+ // Replaced by the id the engine mints — this hook never invents identity.
182
+ id: "pending",
183
+ // Cannot beat any server row in the snapshot's version-guarded merge.
184
+ version: 0,
185
+ // The write addresses a section by KEY; the board groups rows by ID. An
186
+ // unknown section leaves the row ungrouped rather than filing it under a
187
+ // heading that does not exist.
188
+ sectionId: sections.find((section) => section.key === input.sectionKey)?.id ?? "",
189
+ // The server derives the key from the title when one is not sent. Blank
190
+ // rather than a guessed slug: a key that disagrees with the server's is
191
+ // worse than an obviously-absent one, and nothing renders it.
192
+ key: input.key ?? "",
193
+ title: input.title,
194
+ subLine: null,
195
+ status: "OPEN",
196
+ // `=== true`, never `?? false` (hard rule #5): an omitted `mandatory` is
197
+ // the SERVER's default to apply, not this hook's to guess.
198
+ isMandatory: input.mandatory === true,
199
+ // `'NONE'`, never null. The add request carries no `gate` at all — the
200
+ // engine derives it from `phase` — and `'NONE'` is the one value that
201
+ // cannot make a pending item look like it is blocking the trip.
202
+ gate: "NONE",
203
+ dayOffset: null,
204
+ // Appended. The server's own ordering arrives with the canonical row.
205
+ sortOrder: Number.MAX_SAFE_INTEGER,
206
+ completedByManagerId: null,
207
+ performedByKind: null,
208
+ performedById: null,
209
+ completedAt: null,
210
+ // The last reading the SERVER gave this hook, never a device clock (hard
211
+ // rule #6). Blank when nothing has been fetched yet, which is the only
212
+ // honest answer and which the board already prefers `fetchedAt` over.
213
+ updatedAt: fetchedAt ?? ""
214
+ };
215
+ }
216
+ function appendPendingRows(fromAggregate, fromSnapshot) {
217
+ if (fromSnapshot.length === 0) {
218
+ return fromAggregate;
219
+ }
220
+ const known = new Set(fromAggregate.map((row) => row.id));
221
+ const pending = fromSnapshot.filter((row) => !known.has(row.id));
222
+ return pending.length === 0 ? fromAggregate : [...fromAggregate, ...pending];
223
+ }
179
224
  var useChecklistsInternal = createDomainHook("checklists", (tripRef) => {
180
225
  const client = useKaafilClient();
181
226
  const engine = useContext(OfflineEngineContext);
@@ -249,7 +294,33 @@ var useChecklistsInternal = createDomainHook("checklists", (tripRef) => {
249
294
  method: SyncOpMethod.Post,
250
295
  path: `/api/v1/trips/${tripRef}/checklist/items`,
251
296
  operationId: "addChecklistItem",
252
- body: input
297
+ body: input,
298
+ // ── THE OPTIMISTIC CREATE ──────────────────────────────────────
299
+ // Without this the item a manager adds out of signal does not
300
+ // appear until it syncs. It was queued, durable and landed on
301
+ // reconnect the whole time — and from where the manager is
302
+ // standing, work that does not show up is work that was lost, so
303
+ // they add it again.
304
+ //
305
+ // `creates` makes the ENGINE mint the row's temporary id (this
306
+ // hook never invents identifiers) and swap it for the server's
307
+ // canonical row the moment the write lands, in one
308
+ // `snapshot.updated`, so the item is never rendered twice.
309
+ creates: true,
310
+ entity: { listName: "checklist" },
311
+ // Shaped as a real `ChecklistItemDeltaRow` so the board renders it
312
+ // through the same path as every other row rather than a special
313
+ // "pending" branch. `id` is a placeholder the engine replaces with
314
+ // the id it mints; `version: 0` cannot beat any server row in the
315
+ // snapshot's version-guarded merge.
316
+ //
317
+ // The write addresses a section by its `sectionKey`, but the board
318
+ // groups rows by `sectionId`, so the id is resolved from the sections
319
+ // this hook already holds. Adding to a section that does not exist
320
+ // yet resolves to `''` and the row sits ungrouped until the write
321
+ // lands — correct rather than clever: inventing a section id would
322
+ // put the item under a heading that does not exist.
323
+ optimistic: optimisticChecklistItem(input, aggregate.sections, aggregate.fetchedAt)
253
324
  }),
254
325
  // ── THE DESK LANE ─────────────────────────────────────────────────
255
326
  // All five checklist writes take the admin triple, and a desk console
@@ -391,7 +462,7 @@ var useChecklistsInternal = createDomainHook("checklists", (tripRef) => {
391
462
  (input) => client.checklists.agencyTemplates.publish(input),
392
463
  [client]
393
464
  );
394
- const items = syncedAt === void 0 ? aggregate.items : snapshotItems;
465
+ const items = syncedAt === void 0 ? appendPendingRows(aggregate.items, snapshotItems) : snapshotItems;
395
466
  return {
396
467
  items,
397
468
  syncedAt,
@@ -484,6 +555,34 @@ var useCloseoutInternal = createDomainHook("closing-day", (tripRef) => {
484
555
  function useCloseout(tripRef) {
485
556
  return useCloseoutInternal(tripRef);
486
557
  }
558
+ function optimisticCollection(input, syncedAt) {
559
+ const collectedAt = input.collectedAt === void 0 ? "" : normalizeDateTimeInput(input.collectedAt, "collectedAt");
560
+ return {
561
+ // Replaced by the id the engine mints.
562
+ id: "pending",
563
+ version: 0,
564
+ travellerId: input.travellerId,
565
+ amountMinor: input.amountMinor,
566
+ // The request's own default, restated: this tenant's money unit.
567
+ currency: input.currency ?? "INR",
568
+ mode: input.mode,
569
+ reference: input.reference ?? null,
570
+ note: input.note ?? null,
571
+ collectedByManagerId: null,
572
+ performedByKind: null,
573
+ performedById: null,
574
+ collectedAt,
575
+ reportedAt: null,
576
+ voidedAt: null,
577
+ voidReason: null,
578
+ // The server's arithmetic, deliberately not guessed — see above.
579
+ outstandingMinor: null,
580
+ // The last reading the SERVER gave this list, never a device clock
581
+ // (hard rule #6).
582
+ createdAt: syncedAt ?? "",
583
+ updatedAt: syncedAt ?? ""
584
+ };
585
+ }
487
586
  var useCollectionsInternal = createDomainHook("collections", (tripRef) => {
488
587
  const client = useKaafilClient();
489
588
  const {
@@ -533,7 +632,12 @@ var useCollectionsInternal = createDomainHook("collections", (tripRef) => {
533
632
  // hardcoded literal, verified against
534
633
  // `kaafil-js/src/generated/security.ts` this session.
535
634
  operationId: "recordCollection",
536
- body: input
635
+ body: input,
636
+ // A payment recorded out of signal appears at once — see
637
+ // `optimisticCollection` for what it deliberately does not claim.
638
+ creates: true,
639
+ entity: { listName: "collections" },
640
+ optimistic: optimisticCollection(input, syncedAt)
537
641
  }),
538
642
  // The desk lane. `recordCollection` takes the admin triple, and a desk
539
643
  // console mounts no `OfflineShell` — without this the write has no
@@ -1521,6 +1625,34 @@ function useParties(tripRef) {
1521
1625
  remove
1522
1626
  };
1523
1627
  }
1628
+ function optimisticPickupStop(input, syncedAt) {
1629
+ return {
1630
+ // Replaced by the id the engine mints.
1631
+ id: "pending",
1632
+ version: 0,
1633
+ // The request's own default, restated rather than guessed: the SDK's
1634
+ // `kind` is optional and the engine treats an absent one as a pickup.
1635
+ kind: input.kind ?? "PICKUP",
1636
+ name: input.name,
1637
+ locationLabel: input.locationLabel ?? null,
1638
+ lat: input.lat ?? null,
1639
+ lng: input.lng ?? null,
1640
+ scheduledTime: normalizeDateTimeInput(input.scheduledTime, "scheduledTime"),
1641
+ // Appended; the server's ordering arrives with the canonical row.
1642
+ sortOrder: input.sortOrder ?? Number.MAX_SAFE_INTEGER,
1643
+ status: "OPEN",
1644
+ closedAt: null,
1645
+ closedByManagerId: null,
1646
+ performedByKind: null,
1647
+ performedById: null,
1648
+ rollup: "not_started",
1649
+ boardedCount: 0,
1650
+ expectedCount: 0,
1651
+ // The last reading the SERVER gave this list, never a device clock
1652
+ // (hard rule #6).
1653
+ updatedAt: syncedAt ?? ""
1654
+ };
1655
+ }
1524
1656
  var usePickupsInternal = createDomainHook("pickup-points", (tripRef) => {
1525
1657
  const client = useKaafilClient();
1526
1658
  const {
@@ -1544,7 +1676,14 @@ var usePickupsInternal = createDomainHook("pickup-points", (tripRef) => {
1544
1676
  // literal below is checked against `kaafil-js/src/generated/
1545
1677
  // security.ts`'s own operation-id table.
1546
1678
  operationId: "createPickupStop",
1547
- body: input
1679
+ body: input,
1680
+ // A stop added out of signal appears at once, keyed on an id the
1681
+ // ENGINE mints and swapped for the server's row when the write lands
1682
+ // — see `optimisticPickupStop` for why every field here is one the
1683
+ // client can honestly know.
1684
+ creates: true,
1685
+ entity: { listName: "pickups" },
1686
+ optimistic: optimisticPickupStop(input, syncedAt)
1548
1687
  }),
1549
1688
  // The desk lane. `board`, `close` and `reopen` below deliberately get
1550
1689
  // NONE — they are `managerAuth`-only on the wire, so a direct call from
@@ -1690,6 +1829,24 @@ var usePickupsInternal = createDomainHook("pickup-points", (tripRef) => {
1690
1829
  function usePickups(tripRef) {
1691
1830
  return usePickupsInternal(tripRef);
1692
1831
  }
1832
+ function optimisticStayWindow(input, syncedAt) {
1833
+ return {
1834
+ // Replaced by the id the engine mints.
1835
+ id: "pending",
1836
+ version: 0,
1837
+ label: input.label,
1838
+ startDate: normalizeDateTimeInput(input.startDate, "startDate"),
1839
+ endDate: normalizeDateTimeInput(input.endDate, "endDate"),
1840
+ // Appended; the server's ordering arrives with the canonical row.
1841
+ sortOrder: input.sortOrder ?? Number.MAX_SAFE_INTEGER,
1842
+ // A window created by hand has no CRM segment behind it. This is a fact
1843
+ // about the write, not a placeholder.
1844
+ sourceSegmentRef: null,
1845
+ sourceUpdatedAt: null,
1846
+ // The last reading the SERVER gave this list, never a device clock.
1847
+ updatedAt: syncedAt ?? ""
1848
+ };
1849
+ }
1693
1850
  var useRoomingInternal = createDomainHook("rooming", (tripRef) => {
1694
1851
  const client = useKaafilClient();
1695
1852
  const {
@@ -1777,7 +1934,14 @@ var useRoomingInternal = createDomainHook("rooming", (tripRef) => {
1777
1934
  method: SyncOpMethod.Post,
1778
1935
  path: `/api/v1/trips/${tripRef}/rooming/stay-windows`,
1779
1936
  operationId: "createRoomingStayWindow",
1780
- body: input
1937
+ body: input,
1938
+ // A window added out of signal appears at once. Every field of a
1939
+ // stay window is either given by the caller or genuinely absent —
1940
+ // which is exactly what `createRoom` below cannot say, and why only
1941
+ // this one of the two gets an optimistic row.
1942
+ creates: true,
1943
+ entity: { listName: "stayWindows" },
1944
+ optimistic: optimisticStayWindow(input, windowsSyncedAt)
1781
1945
  }),
1782
1946
  direct: (liveClient, input) => liveClient.rooming.stayWindows.create({ tripRef, ...input })
1783
1947
  });
@@ -2166,5 +2330,5 @@ function useVendors(tripRef, agencyRef) {
2166
2330
  }
2167
2331
 
2168
2332
  export { ERROR_HANDLING_PATH, FORM_FIELD_KIND_SINGLE_BOOLEAN, classifyError, createDomainHook, useChecklists, useCloseout, useCollections, useExpenses, useFiles, useFloat, useForms, useItinerary, useManagerToday, useManagers, useParties, usePickups, useRooming, useSeating, useSnapshotList, useTravellerProfile, useVendors };
2169
- //# sourceMappingURL=chunk-RSC2ZJUP.js.map
2170
- //# sourceMappingURL=chunk-RSC2ZJUP.js.map
2333
+ //# sourceMappingURL=chunk-JHMN6Q5R.js.map
2334
+ //# sourceMappingURL=chunk-JHMN6Q5R.js.map