kaafil-react-uikit 0.3.0 → 0.4.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 (62) hide show
  1. package/CHANGELOG.md +54 -0
  2. package/dist/admin/index.cjs +565 -387
  3. package/dist/admin/index.cjs.map +1 -1
  4. package/dist/admin/index.d.cts +2 -2
  5. package/dist/admin/index.d.ts +2 -2
  6. package/dist/admin/index.js +231 -53
  7. package/dist/admin/index.js.map +1 -1
  8. package/dist/{chunk-YTSYRLGS.js → chunk-2LMFSKZU.js} +56 -17
  9. package/dist/chunk-2LMFSKZU.js.map +1 -0
  10. package/dist/{chunk-BBC5EX5O.cjs → chunk-2XW5EIMS.cjs} +17 -17
  11. package/dist/{chunk-BBC5EX5O.cjs.map → chunk-2XW5EIMS.cjs.map} +1 -1
  12. package/dist/{chunk-YU2242AR.js → chunk-3BEQYIFU.js} +5 -5
  13. package/dist/{chunk-YU2242AR.js.map → chunk-3BEQYIFU.js.map} +1 -1
  14. package/dist/{chunk-UALMCHNW.cjs → chunk-3N2EQ2KC.cjs} +84 -36
  15. package/dist/chunk-3N2EQ2KC.cjs.map +1 -0
  16. package/dist/{chunk-57SUK3GD.cjs → chunk-4QYI7TOF.cjs} +7 -7
  17. package/dist/{chunk-57SUK3GD.cjs.map → chunk-4QYI7TOF.cjs.map} +1 -1
  18. package/dist/{chunk-ECCQW5LN.cjs → chunk-6BY2NPBZ.cjs} +4 -4
  19. package/dist/{chunk-ECCQW5LN.cjs.map → chunk-6BY2NPBZ.cjs.map} +1 -1
  20. package/dist/{chunk-YNHOPYBK.cjs → chunk-7356B6YS.cjs} +12 -12
  21. package/dist/{chunk-YNHOPYBK.cjs.map → chunk-7356B6YS.cjs.map} +1 -1
  22. package/dist/{chunk-A4Z2YBEF.js → chunk-7G6IENKN.js} +84 -36
  23. package/dist/chunk-7G6IENKN.js.map +1 -0
  24. package/dist/{chunk-MNUCVVIE.cjs → chunk-A7C74SJT.cjs} +302 -148
  25. package/dist/chunk-A7C74SJT.cjs.map +1 -0
  26. package/dist/{chunk-KW5LH6KV.js → chunk-CLHAJBJS.js} +3 -3
  27. package/dist/{chunk-KW5LH6KV.js.map → chunk-CLHAJBJS.js.map} +1 -1
  28. package/dist/{chunk-GJ2J3PYN.js → chunk-E6ER25BG.js} +3 -3
  29. package/dist/{chunk-GJ2J3PYN.js.map → chunk-E6ER25BG.js.map} +1 -1
  30. package/dist/{chunk-HACH2NUM.cjs → chunk-KETEED2T.cjs} +9 -9
  31. package/dist/{chunk-HACH2NUM.cjs.map → chunk-KETEED2T.cjs.map} +1 -1
  32. package/dist/{chunk-RWLO6IFX.js → chunk-KTEXDGAA.js} +3 -3
  33. package/dist/{chunk-RWLO6IFX.js.map → chunk-KTEXDGAA.js.map} +1 -1
  34. package/dist/{chunk-VLP323AD.js → chunk-RBIEMGHT.js} +3 -3
  35. package/dist/{chunk-VLP323AD.js.map → chunk-RBIEMGHT.js.map} +1 -1
  36. package/dist/{chunk-WTTGPWMR.js → chunk-WPQB7JWS.js} +227 -73
  37. package/dist/chunk-WPQB7JWS.js.map +1 -0
  38. package/dist/{chunk-FVK7HMQ5.cjs → chunk-XBLAVNP3.cjs} +88 -48
  39. package/dist/chunk-XBLAVNP3.cjs.map +1 -0
  40. package/dist/core/index.cjs +124 -121
  41. package/dist/core/index.cjs.map +1 -1
  42. package/dist/core/index.d.cts +10 -1
  43. package/dist/core/index.d.ts +10 -1
  44. package/dist/core/index.js +20 -19
  45. package/dist/core/index.js.map +1 -1
  46. package/dist/index.css +1 -1
  47. package/dist/manager/index.cjs +239 -239
  48. package/dist/manager/index.js +6 -6
  49. package/dist/tokens.json +5013 -0
  50. package/dist/traveller/index.cjs +46 -40
  51. package/dist/traveller/index.cjs.map +1 -1
  52. package/dist/traveller/index.js +16 -10
  53. package/dist/traveller/index.js.map +1 -1
  54. package/dist/{useAgencyTrip-BUYSIaC2.d.cts → useAgencyTrip-C1YmfuQq.d.cts} +35 -1
  55. package/dist/{useAgencyTrip-BzyJB1D9.d.ts → useAgencyTrip-gZB0NILH.d.ts} +35 -1
  56. package/package.json +4 -3
  57. package/dist/chunk-A4Z2YBEF.js.map +0 -1
  58. package/dist/chunk-FVK7HMQ5.cjs.map +0 -1
  59. package/dist/chunk-MNUCVVIE.cjs.map +0 -1
  60. package/dist/chunk-UALMCHNW.cjs.map +0 -1
  61. package/dist/chunk-WTTGPWMR.js.map +0 -1
  62. package/dist/chunk-YTSYRLGS.js.map +0 -1
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- var chunkUALMCHNW_cjs = require('./chunk-UALMCHNW.cjs');
3
+ var chunk3N2EQ2KC_cjs = require('./chunk-3N2EQ2KC.cjs');
4
4
  var client = require('kaafil-js/client');
5
5
  var react = require('react');
6
6
 
@@ -99,8 +99,8 @@ function ensureTripPulled(engine, tripRef) {
99
99
 
100
100
  // src/core/hooks/useSnapshotList.ts
101
101
  function useSnapshotList(tripRef, listName, options) {
102
- const engine = react.useContext(chunkUALMCHNW_cjs.OfflineEngineContext);
103
- const client = react.useContext(chunkUALMCHNW_cjs.KaafilClientContext);
102
+ const engine = react.useContext(chunk3N2EQ2KC_cjs.OfflineEngineContext);
103
+ const client = react.useContext(chunk3N2EQ2KC_cjs.KaafilClientContext);
104
104
  const [rows, setRows] = react.useState(
105
105
  () => engine === null ? [] : engine.snapshot.list(tripRef, listName)
106
106
  );
@@ -161,15 +161,15 @@ function useSnapshotList(tripRef, listName, options) {
161
161
  // src/core/internal/createDomainHook.ts
162
162
  function createDomainHook(moduleKey, build) {
163
163
  return function useDomainHook(tripRef) {
164
- const { rows, loaded } = chunkUALMCHNW_cjs.useCapabilityRows(tripRef);
164
+ const { rows, loaded } = chunk3N2EQ2KC_cjs.useCapabilityRows(tripRef);
165
165
  const ready = build(tripRef);
166
166
  if (!loaded) {
167
167
  return { status: "loading" };
168
168
  }
169
169
  const row = rows.find((candidate) => candidate.capability === moduleKey);
170
- const triple = row === void 0 ? chunkUALMCHNW_cjs.UNKNOWN_CAPABILITY_TRIPLE : chunkUALMCHNW_cjs.deriveCapabilityTriple(row);
170
+ const triple = row === void 0 ? chunk3N2EQ2KC_cjs.UNKNOWN_CAPABILITY_TRIPLE : chunk3N2EQ2KC_cjs.deriveCapabilityTriple(row);
171
171
  if (triple.status !== "lit") {
172
- const reason = chunkUALMCHNW_cjs.darkReasonFor(triple);
172
+ const reason = chunk3N2EQ2KC_cjs.darkReasonFor(triple);
173
173
  return { status: "dark", reason };
174
174
  }
175
175
  return { status: "ready", ...ready };
@@ -177,6 +177,43 @@ function createDomainHook(moduleKey, build) {
177
177
  }
178
178
 
179
179
  // src/core/hooks/useChecklists.ts
180
+ function optimisticChecklistItem(input, sections, fetchedAt) {
181
+ return {
182
+ // Replaced by the id the engine mints — this hook never invents identity.
183
+ id: "pending",
184
+ // Cannot beat any server row in the snapshot's version-guarded merge.
185
+ version: 0,
186
+ // The write addresses a section by KEY; the board groups rows by ID. An
187
+ // unknown section leaves the row ungrouped rather than filing it under a
188
+ // heading that does not exist.
189
+ sectionId: sections.find((section) => section.key === input.sectionKey)?.id ?? "",
190
+ // The server derives the key from the title when one is not sent. Blank
191
+ // rather than a guessed slug: a key that disagrees with the server's is
192
+ // worse than an obviously-absent one, and nothing renders it.
193
+ key: input.key ?? "",
194
+ title: input.title,
195
+ subLine: null,
196
+ status: "OPEN",
197
+ // `=== true`, never `?? false` (hard rule #5): an omitted `mandatory` is
198
+ // the SERVER's default to apply, not this hook's to guess.
199
+ isMandatory: input.mandatory === true,
200
+ // `'NONE'`, never null. The add request carries no `gate` at all — the
201
+ // engine derives it from `phase` — and `'NONE'` is the one value that
202
+ // cannot make a pending item look like it is blocking the trip.
203
+ gate: "NONE",
204
+ dayOffset: null,
205
+ // Appended. The server's own ordering arrives with the canonical row.
206
+ sortOrder: Number.MAX_SAFE_INTEGER,
207
+ completedByManagerId: null,
208
+ performedByKind: null,
209
+ performedById: null,
210
+ completedAt: null,
211
+ // The last reading the SERVER gave this hook, never a device clock (hard
212
+ // rule #6). Blank when nothing has been fetched yet, which is the only
213
+ // honest answer and which the board already prefers `fetchedAt` over.
214
+ updatedAt: fetchedAt ?? ""
215
+ };
216
+ }
180
217
  function appendPendingRows(fromAggregate, fromSnapshot) {
181
218
  if (fromSnapshot.length === 0) {
182
219
  return fromAggregate;
@@ -186,8 +223,8 @@ function appendPendingRows(fromAggregate, fromSnapshot) {
186
223
  return pending.length === 0 ? fromAggregate : [...fromAggregate, ...pending];
187
224
  }
188
225
  var useChecklistsInternal = createDomainHook("checklists", (tripRef) => {
189
- const client$1 = chunkUALMCHNW_cjs.useKaafilClient();
190
- const engine = react.useContext(chunkUALMCHNW_cjs.OfflineEngineContext);
226
+ const client$1 = chunk3N2EQ2KC_cjs.useKaafilClient();
227
+ const engine = react.useContext(chunk3N2EQ2KC_cjs.OfflineEngineContext);
191
228
  const { rows: snapshotItems, syncedAt } = useSnapshotList(
192
229
  tripRef,
193
230
  "checklist"
@@ -251,7 +288,7 @@ var useChecklistsInternal = createDomainHook("checklists", (tripRef) => {
251
288
  void refreshAggregate();
252
289
  });
253
290
  }, [engine, refreshAggregate]);
254
- const addItemMutation = chunkUALMCHNW_cjs.useOfflineMutation({
291
+ const addItemMutation = chunk3N2EQ2KC_cjs.useOfflineMutation({
255
292
  tripRef,
256
293
  enqueue: (engine2, input) => engine2.enqueue({
257
294
  tripRef,
@@ -284,28 +321,7 @@ var useChecklistsInternal = createDomainHook("checklists", (tripRef) => {
284
321
  // yet resolves to `''` and the row sits ungrouped until the write
285
322
  // lands — correct rather than clever: inventing a section id would
286
323
  // put the item under a heading that does not exist.
287
- optimistic: {
288
- id: "pending",
289
- version: 0,
290
- sectionId: aggregate.sections.find((section) => section.key === input.sectionKey)?.id ?? "",
291
- key: input.key ?? null,
292
- title: input.title,
293
- subLine: null,
294
- status: "OPEN",
295
- // `=== true`, never `?? false` (hard rule #5): an omitted
296
- // `mandatory` is the SERVER's default to apply, not this hook's to
297
- // guess. The optimistic row shows it unstarred for the moment it
298
- // takes the write to land, and the canonical row replaces it.
299
- isMandatory: input.mandatory === true,
300
- gate: null,
301
- dayOffset: null,
302
- sortOrder: Number.MAX_SAFE_INTEGER,
303
- completedByManagerId: null,
304
- performedByKind: null,
305
- performedById: null,
306
- completedAt: null,
307
- updatedAt: null
308
- }
324
+ optimistic: optimisticChecklistItem(input, aggregate.sections, aggregate.fetchedAt)
309
325
  }),
310
326
  // ── THE DESK LANE ─────────────────────────────────────────────────
311
327
  // All five checklist writes take the admin triple, and a desk console
@@ -317,7 +333,7 @@ var useChecklistsInternal = createDomainHook("checklists", (tripRef) => {
317
333
  // lane for exactly that reason.
318
334
  direct: (liveClient, input) => liveClient.checklists.items.add({ tripRef, ...input })
319
335
  });
320
- const patchItemMutation = chunkUALMCHNW_cjs.useOfflineMutation({
336
+ const patchItemMutation = chunk3N2EQ2KC_cjs.useOfflineMutation({
321
337
  tripRef,
322
338
  enqueue: (engine2, input) => {
323
339
  const { itemId, version, ...body } = input;
@@ -332,7 +348,7 @@ var useChecklistsInternal = createDomainHook("checklists", (tripRef) => {
332
348
  },
333
349
  direct: (liveClient, input) => liveClient.checklists.items.patch({ tripRef, ...input })
334
350
  });
335
- const removeItemMutation = chunkUALMCHNW_cjs.useOfflineMutation({
351
+ const removeItemMutation = chunk3N2EQ2KC_cjs.useOfflineMutation({
336
352
  tripRef,
337
353
  enqueue: (engine2, input) => {
338
354
  const { itemId, version } = input;
@@ -346,7 +362,7 @@ var useChecklistsInternal = createDomainHook("checklists", (tripRef) => {
346
362
  },
347
363
  direct: (liveClient, input) => liveClient.checklists.items.remove({ tripRef, ...input })
348
364
  });
349
- const toggleItemMutation = chunkUALMCHNW_cjs.useOfflineMutation({
365
+ const toggleItemMutation = chunk3N2EQ2KC_cjs.useOfflineMutation({
350
366
  tripRef,
351
367
  enqueue: (engine2, input) => {
352
368
  const { itemId, ...body } = input;
@@ -362,7 +378,7 @@ var useChecklistsInternal = createDomainHook("checklists", (tripRef) => {
362
378
  },
363
379
  direct: (liveClient, input) => liveClient.checklists.items.toggle({ tripRef, ...input })
364
380
  });
365
- const pullTemplateMutation = chunkUALMCHNW_cjs.useOfflineMutation({
381
+ const pullTemplateMutation = chunk3N2EQ2KC_cjs.useOfflineMutation({
366
382
  tripRef,
367
383
  enqueue: (engine2, input) => engine2.enqueue({
368
384
  tripRef,
@@ -469,7 +485,7 @@ function useChecklists(tripRef) {
469
485
  return useChecklistsInternal(tripRef);
470
486
  }
471
487
  var useCloseoutInternal = createDomainHook("closing-day", (tripRef) => {
472
- const client = chunkUALMCHNW_cjs.useKaafilClient();
488
+ const client = chunk3N2EQ2KC_cjs.useKaafilClient();
473
489
  const [aggregate, setAggregate] = react.useState(void 0);
474
490
  const [loaded, setLoaded] = react.useState(false);
475
491
  const [lastFetchFailed, setLastFetchFailed] = react.useState(false);
@@ -540,8 +556,36 @@ var useCloseoutInternal = createDomainHook("closing-day", (tripRef) => {
540
556
  function useCloseout(tripRef) {
541
557
  return useCloseoutInternal(tripRef);
542
558
  }
559
+ function optimisticCollection(input, syncedAt) {
560
+ const collectedAt = input.collectedAt === void 0 ? "" : client.normalizeDateTimeInput(input.collectedAt, "collectedAt");
561
+ return {
562
+ // Replaced by the id the engine mints.
563
+ id: "pending",
564
+ version: 0,
565
+ travellerId: input.travellerId,
566
+ amountMinor: input.amountMinor,
567
+ // The request's own default, restated: this tenant's money unit.
568
+ currency: input.currency ?? "INR",
569
+ mode: input.mode,
570
+ reference: input.reference ?? null,
571
+ note: input.note ?? null,
572
+ collectedByManagerId: null,
573
+ performedByKind: null,
574
+ performedById: null,
575
+ collectedAt,
576
+ reportedAt: null,
577
+ voidedAt: null,
578
+ voidReason: null,
579
+ // The server's arithmetic, deliberately not guessed — see above.
580
+ outstandingMinor: null,
581
+ // The last reading the SERVER gave this list, never a device clock
582
+ // (hard rule #6).
583
+ createdAt: syncedAt ?? "",
584
+ updatedAt: syncedAt ?? ""
585
+ };
586
+ }
543
587
  var useCollectionsInternal = createDomainHook("collections", (tripRef) => {
544
- const client$1 = chunkUALMCHNW_cjs.useKaafilClient();
588
+ const client$1 = chunk3N2EQ2KC_cjs.useKaafilClient();
545
589
  const {
546
590
  rows: collections,
547
591
  syncedAt,
@@ -578,7 +622,7 @@ var useCollectionsInternal = createDomainHook("collections", (tripRef) => {
578
622
  react.useEffect(() => {
579
623
  void refreshEligible(eligibleStatus);
580
624
  }, [refreshEligible, eligibleStatus]);
581
- const recordMutation = chunkUALMCHNW_cjs.useOfflineMutation({
625
+ const recordMutation = chunk3N2EQ2KC_cjs.useOfflineMutation({
582
626
  tripRef,
583
627
  enqueue: (engine, input) => engine.enqueue({
584
628
  tripRef,
@@ -589,7 +633,12 @@ var useCollectionsInternal = createDomainHook("collections", (tripRef) => {
589
633
  // hardcoded literal, verified against
590
634
  // `kaafil-js/src/generated/security.ts` this session.
591
635
  operationId: "recordCollection",
592
- body: input
636
+ body: input,
637
+ // A payment recorded out of signal appears at once — see
638
+ // `optimisticCollection` for what it deliberately does not claim.
639
+ creates: true,
640
+ entity: { listName: "collections" },
641
+ optimistic: optimisticCollection(input, syncedAt)
593
642
  }),
594
643
  // The desk lane. `recordCollection` takes the admin triple, and a desk
595
644
  // console mounts no `OfflineShell` — without this the write has no
@@ -605,7 +654,7 @@ var useCollectionsInternal = createDomainHook("collections", (tripRef) => {
605
654
  },
606
655
  [recordMutate, refreshEligible]
607
656
  );
608
- const voidMutation = chunkUALMCHNW_cjs.useOfflineMutation({
657
+ const voidMutation = chunk3N2EQ2KC_cjs.useOfflineMutation({
609
658
  tripRef,
610
659
  enqueue: (engine, input) => {
611
660
  const { collectionId, version, ...body } = input;
@@ -649,7 +698,7 @@ function useCollections(tripRef) {
649
698
  return useCollectionsInternal(tripRef);
650
699
  }
651
700
  var useExpensesInternal = createDomainHook("expenses", (tripRef) => {
652
- const client$1 = chunkUALMCHNW_cjs.useKaafilClient();
701
+ const client$1 = chunk3N2EQ2KC_cjs.useKaafilClient();
653
702
  const {
654
703
  rows: expenses,
655
704
  syncedAt,
@@ -678,9 +727,19 @@ var useExpensesInternal = createDomainHook("expenses", (tripRef) => {
678
727
  react.useEffect(() => {
679
728
  void refreshTotals();
680
729
  }, [refreshTotals]);
681
- const logMutation = chunkUALMCHNW_cjs.useOfflineMutation({
730
+ const engine = react.useContext(chunk3N2EQ2KC_cjs.OfflineEngineContext);
731
+ react.useEffect(() => {
732
+ if (engine === null) {
733
+ return;
734
+ }
735
+ const unsubscribe = engine.events.on("sync.drained", () => {
736
+ void refreshTotals();
737
+ });
738
+ return unsubscribe;
739
+ }, [engine, refreshTotals]);
740
+ const logMutation = chunk3N2EQ2KC_cjs.useOfflineMutation({
682
741
  tripRef,
683
- enqueue: (engine, input) => engine.enqueue({
742
+ enqueue: (engine2, input) => engine2.enqueue({
684
743
  tripRef,
685
744
  method: client.SyncOpMethod.Post,
686
745
  path: `/api/v1/trips/${tripRef}/expenses`,
@@ -699,11 +758,11 @@ var useExpensesInternal = createDomainHook("expenses", (tripRef) => {
699
758
  // reimbursement, and an admin has no business standing in for them.
700
759
  direct: (liveClient, input) => liveClient.expenses.log({ tripRef, ...input })
701
760
  });
702
- const linkReceiptMutation = chunkUALMCHNW_cjs.useOfflineMutation({
761
+ const linkReceiptMutation = chunk3N2EQ2KC_cjs.useOfflineMutation({
703
762
  tripRef,
704
- enqueue: (engine, input) => {
763
+ enqueue: (engine2, input) => {
705
764
  const { expenseId, ...body } = input;
706
- return engine.enqueue({
765
+ return engine2.enqueue({
707
766
  tripRef,
708
767
  method: client.SyncOpMethod.Patch,
709
768
  path: `/api/v1/trips/${tripRef}/expenses/${expenseId}/receipt`,
@@ -722,11 +781,11 @@ var useExpensesInternal = createDomainHook("expenses", (tripRef) => {
722
781
  // Widening it would mean either breaking rule #4 or making the key
723
782
  // optional on the wire, neither of which belongs in a UIKit pass.
724
783
  });
725
- const voidMutation = chunkUALMCHNW_cjs.useOfflineMutation({
784
+ const voidMutation = chunk3N2EQ2KC_cjs.useOfflineMutation({
726
785
  tripRef,
727
- enqueue: (engine, input) => {
786
+ enqueue: (engine2, input) => {
728
787
  const { expenseId, version, ...body } = input;
729
- return engine.enqueue({
788
+ return engine2.enqueue({
730
789
  tripRef,
731
790
  method: client.SyncOpMethod.Delete,
732
791
  path: `/api/v1/trips/${tripRef}/expenses/${expenseId}/void`,
@@ -737,11 +796,11 @@ var useExpensesInternal = createDomainHook("expenses", (tripRef) => {
737
796
  },
738
797
  direct: (liveClient, input) => liveClient.expenses.void({ tripRef, ...input })
739
798
  });
740
- const submitClaimMutation = chunkUALMCHNW_cjs.useOfflineMutation({
799
+ const submitClaimMutation = chunk3N2EQ2KC_cjs.useOfflineMutation({
741
800
  tripRef,
742
- enqueue: (engine, input) => {
801
+ enqueue: (engine2, input) => {
743
802
  const { expenseId } = input;
744
- return engine.enqueue({
803
+ return engine2.enqueue({
745
804
  tripRef,
746
805
  method: client.SyncOpMethod.Post,
747
806
  path: `/api/v1/trips/${tripRef}/expenses/${expenseId}/claim`,
@@ -750,11 +809,11 @@ var useExpensesInternal = createDomainHook("expenses", (tripRef) => {
750
809
  });
751
810
  }
752
811
  });
753
- const withdrawClaimMutation = chunkUALMCHNW_cjs.useOfflineMutation({
812
+ const withdrawClaimMutation = chunk3N2EQ2KC_cjs.useOfflineMutation({
754
813
  tripRef,
755
- enqueue: (engine, input) => {
814
+ enqueue: (engine2, input) => {
756
815
  const { expenseId, version } = input;
757
- return engine.enqueue({
816
+ return engine2.enqueue({
758
817
  tripRef,
759
818
  method: client.SyncOpMethod.Delete,
760
819
  path: `/api/v1/trips/${tripRef}/expenses/${expenseId}/claim/withdraw`,
@@ -792,7 +851,7 @@ function useExpenses(tripRef) {
792
851
  }
793
852
  var DEFAULT_MAX_ATTEMPTS = 3;
794
853
  function useFiles(context) {
795
- const client = chunkUALMCHNW_cjs.useKaafilClient();
854
+ const client = chunk3N2EQ2KC_cjs.useKaafilClient();
796
855
  const { tripRef } = context;
797
856
  const request = react.useCallback(
798
857
  (input) => client.files.request({ ...input, tripRef }),
@@ -864,7 +923,7 @@ function useFiles(context) {
864
923
  return { request, confirm, meta, url, list, managerView, upload };
865
924
  }
866
925
  var useFloatInternal = createDomainHook("float", (tripRef) => {
867
- const client$1 = chunkUALMCHNW_cjs.useKaafilClient();
926
+ const client$1 = chunk3N2EQ2KC_cjs.useKaafilClient();
868
927
  const { rows: movements, syncedAt } = useSnapshotList(tripRef, "float");
869
928
  const [summaryRows, setSummaryRows] = react.useState([]);
870
929
  const [summaryLoaded, setSummaryLoaded] = react.useState(false);
@@ -884,7 +943,7 @@ var useFloatInternal = createDomainHook("float", (tripRef) => {
884
943
  react.useEffect(() => {
885
944
  void refreshSummary();
886
945
  }, [refreshSummary]);
887
- const issueMutation = chunkUALMCHNW_cjs.useOfflineMutation({
946
+ const issueMutation = chunk3N2EQ2KC_cjs.useOfflineMutation({
888
947
  tripRef,
889
948
  enqueue: (engine, input) => engine.enqueue({
890
949
  tripRef,
@@ -902,7 +961,7 @@ var useFloatInternal = createDomainHook("float", (tripRef) => {
902
961
  // transport at all.
903
962
  direct: (liveClient, input) => liveClient.float.issue({ tripRef, ...input })
904
963
  });
905
- const returnMutation = chunkUALMCHNW_cjs.useOfflineMutation({
964
+ const returnMutation = chunk3N2EQ2KC_cjs.useOfflineMutation({
906
965
  tripRef,
907
966
  enqueue: (engine, input) => engine.enqueue({
908
967
  tripRef,
@@ -913,7 +972,7 @@ var useFloatInternal = createDomainHook("float", (tripRef) => {
913
972
  }),
914
973
  direct: (liveClient, input) => liveClient.float.return({ tripRef, ...input })
915
974
  });
916
- const adjustMutation = chunkUALMCHNW_cjs.useOfflineMutation({
975
+ const adjustMutation = chunk3N2EQ2KC_cjs.useOfflineMutation({
917
976
  tripRef,
918
977
  enqueue: (engine, input) => engine.enqueue({
919
978
  tripRef,
@@ -976,8 +1035,8 @@ function useFloat(tripRef) {
976
1035
  }
977
1036
  var FORM_FIELD_KIND_SINGLE_BOOLEAN = "CHECKBOX";
978
1037
  var useFormsInternal = createDomainHook("forms", (tripRef) => {
979
- const client$1 = chunkUALMCHNW_cjs.useKaafilClient();
980
- const engine = react.useContext(chunkUALMCHNW_cjs.OfflineEngineContext);
1038
+ const client$1 = chunk3N2EQ2KC_cjs.useKaafilClient();
1039
+ const engine = react.useContext(chunk3N2EQ2KC_cjs.OfflineEngineContext);
981
1040
  const [forms, setForms] = react.useState([]);
982
1041
  const [syncedAt, setSyncedAt] = react.useState(void 0);
983
1042
  const refreshForms = react.useCallback(async () => {
@@ -1022,7 +1081,7 @@ var useFormsInternal = createDomainHook("forms", (tripRef) => {
1022
1081
  },
1023
1082
  [client$1, tripRef]
1024
1083
  );
1025
- const submitMutation = chunkUALMCHNW_cjs.useOfflineMutation({
1084
+ const submitMutation = chunk3N2EQ2KC_cjs.useOfflineMutation({
1026
1085
  tripRef,
1027
1086
  enqueue: (engine2, input) => {
1028
1087
  const { formId, ...body } = input;
@@ -1192,7 +1251,7 @@ function isLiveItineraryItem(row) {
1192
1251
  return !("_tombstone" in row);
1193
1252
  }
1194
1253
  function useItinerary(tripRef) {
1195
- const client$1 = chunkUALMCHNW_cjs.useKaafilClient();
1254
+ const client$1 = chunk3N2EQ2KC_cjs.useKaafilClient();
1196
1255
  const [trip, setTrip] = react.useState(void 0);
1197
1256
  const [initialDayIso, setInitialDayIso] = react.useState(void 0);
1198
1257
  const [canAddItems, setCanAddItems] = react.useState(false);
@@ -1221,6 +1280,16 @@ function useItinerary(tripRef) {
1221
1280
  react.useEffect(() => {
1222
1281
  void refresh();
1223
1282
  }, [refresh]);
1283
+ const engine = react.useContext(chunk3N2EQ2KC_cjs.OfflineEngineContext);
1284
+ const refreshAfterDrain = react.useCallback(() => {
1285
+ if (engine === null) {
1286
+ return;
1287
+ }
1288
+ const unsubscribe = engine.events.on("sync.drained", () => {
1289
+ unsubscribe();
1290
+ void refresh();
1291
+ });
1292
+ }, [engine, refresh]);
1224
1293
  const [changeLog, setChangeLog] = react.useState([]);
1225
1294
  const [changeLogLoaded, setChangeLogLoaded] = react.useState(false);
1226
1295
  const [changeLogFetchFailed, setChangeLogFetchFailed] = react.useState(false);
@@ -1237,11 +1306,11 @@ function useItinerary(tripRef) {
1237
1306
  },
1238
1307
  [client$1, tripRef]
1239
1308
  );
1240
- const patchDayMutation = chunkUALMCHNW_cjs.useOfflineMutation({
1309
+ const patchDayMutation = chunk3N2EQ2KC_cjs.useOfflineMutation({
1241
1310
  tripRef,
1242
- enqueue: (engine, input) => {
1311
+ enqueue: (engine2, input) => {
1243
1312
  const { dayIndex, version, ...body } = input;
1244
- return engine.enqueue({
1313
+ return engine2.enqueue({
1245
1314
  tripRef,
1246
1315
  method: client.SyncOpMethod.Patch,
1247
1316
  path: `/api/v1/trips/${tripRef}/itinerary/days/${dayIndex}`,
@@ -1257,13 +1326,14 @@ function useItinerary(tripRef) {
1257
1326
  async (input) => {
1258
1327
  const op = await patchDayMutate(input);
1259
1328
  void refresh();
1329
+ refreshAfterDrain();
1260
1330
  return op;
1261
1331
  },
1262
- [patchDayMutate, refresh]
1332
+ [patchDayMutate, refresh, refreshAfterDrain]
1263
1333
  );
1264
- const addItemMutation = chunkUALMCHNW_cjs.useOfflineMutation({
1334
+ const addItemMutation = chunk3N2EQ2KC_cjs.useOfflineMutation({
1265
1335
  tripRef,
1266
- enqueue: (engine, input) => engine.enqueue({
1336
+ enqueue: (engine2, input) => engine2.enqueue({
1267
1337
  tripRef,
1268
1338
  method: client.SyncOpMethod.Post,
1269
1339
  path: `/api/v1/trips/${tripRef}/itinerary/items`,
@@ -1277,15 +1347,16 @@ function useItinerary(tripRef) {
1277
1347
  async (input) => {
1278
1348
  const op = await addItemMutate(input);
1279
1349
  void refresh();
1350
+ refreshAfterDrain();
1280
1351
  return op;
1281
1352
  },
1282
- [addItemMutate, refresh]
1353
+ [addItemMutate, refresh, refreshAfterDrain]
1283
1354
  );
1284
- const patchItemMutation = chunkUALMCHNW_cjs.useOfflineMutation({
1355
+ const patchItemMutation = chunk3N2EQ2KC_cjs.useOfflineMutation({
1285
1356
  tripRef,
1286
- enqueue: (engine, input) => {
1357
+ enqueue: (engine2, input) => {
1287
1358
  const { itemId, version, ...body } = input;
1288
- return engine.enqueue({
1359
+ return engine2.enqueue({
1289
1360
  tripRef,
1290
1361
  method: client.SyncOpMethod.Patch,
1291
1362
  path: `/api/v1/trips/${tripRef}/itinerary/items/${itemId}`,
@@ -1301,15 +1372,16 @@ function useItinerary(tripRef) {
1301
1372
  async (input) => {
1302
1373
  const op = await patchItemMutate(input);
1303
1374
  void refresh();
1375
+ refreshAfterDrain();
1304
1376
  return op;
1305
1377
  },
1306
- [patchItemMutate, refresh]
1378
+ [patchItemMutate, refresh, refreshAfterDrain]
1307
1379
  );
1308
- const removeItemMutation = chunkUALMCHNW_cjs.useOfflineMutation({
1380
+ const removeItemMutation = chunk3N2EQ2KC_cjs.useOfflineMutation({
1309
1381
  tripRef,
1310
- enqueue: (engine, input) => {
1382
+ enqueue: (engine2, input) => {
1311
1383
  const { itemId, version } = input;
1312
- return engine.enqueue({
1384
+ return engine2.enqueue({
1313
1385
  tripRef,
1314
1386
  method: client.SyncOpMethod.Delete,
1315
1387
  path: `/api/v1/trips/${tripRef}/itinerary/items/${itemId}`,
@@ -1324,15 +1396,16 @@ function useItinerary(tripRef) {
1324
1396
  async (input) => {
1325
1397
  const op = await removeItemMutate(input);
1326
1398
  void refresh();
1399
+ refreshAfterDrain();
1327
1400
  return op;
1328
1401
  },
1329
- [removeItemMutate, refresh]
1402
+ [removeItemMutate, refresh, refreshAfterDrain]
1330
1403
  );
1331
- const reorderItemMutation = chunkUALMCHNW_cjs.useOfflineMutation({
1404
+ const reorderItemMutation = chunk3N2EQ2KC_cjs.useOfflineMutation({
1332
1405
  tripRef,
1333
- enqueue: (engine, input) => {
1406
+ enqueue: (engine2, input) => {
1334
1407
  const { itemId, ...body } = input;
1335
- return engine.enqueue({
1408
+ return engine2.enqueue({
1336
1409
  tripRef,
1337
1410
  method: client.SyncOpMethod.Post,
1338
1411
  path: `/api/v1/trips/${tripRef}/itinerary/items/${itemId}/reorder`,
@@ -1347,9 +1420,10 @@ function useItinerary(tripRef) {
1347
1420
  async (input) => {
1348
1421
  const op = await reorderItemMutate(input);
1349
1422
  void refresh();
1423
+ refreshAfterDrain();
1350
1424
  return op;
1351
1425
  },
1352
- [reorderItemMutate, refresh]
1426
+ [reorderItemMutate, refresh, refreshAfterDrain]
1353
1427
  );
1354
1428
  if (!loaded && !lastFetchFailed) {
1355
1429
  return { status: "loading" };
@@ -1381,12 +1455,12 @@ function useItinerary(tripRef) {
1381
1455
  };
1382
1456
  }
1383
1457
  function useManagers(tripRef) {
1384
- const client = chunkUALMCHNW_cjs.useKaafilClient();
1385
- const persona = chunkUALMCHNW_cjs.usePersona();
1458
+ const client = chunk3N2EQ2KC_cjs.useKaafilClient();
1459
+ const persona = chunk3N2EQ2KC_cjs.usePersona();
1386
1460
  const [result, setResult] = react.useState({ status: "loading" });
1387
1461
  react.useEffect(() => {
1388
1462
  if (persona === "share") {
1389
- if (chunkUALMCHNW_cjs.isDevelopment()) {
1463
+ if (chunk3N2EQ2KC_cjs.isDevelopment()) {
1390
1464
  throw new Error(
1391
1465
  "useManagers() was called from a share session \u2014 it is manager/agencyAdmin only."
1392
1466
  );
@@ -1411,7 +1485,7 @@ function useManagers(tripRef) {
1411
1485
  return result;
1412
1486
  }
1413
1487
  function useManagerToday(tripRef) {
1414
- const client = chunkUALMCHNW_cjs.useKaafilClient();
1488
+ const client = chunk3N2EQ2KC_cjs.useKaafilClient();
1415
1489
  const [result, setResult] = react.useState({ status: "loading" });
1416
1490
  react.useEffect(() => {
1417
1491
  let cancelled = false;
@@ -1437,7 +1511,7 @@ function isLiveParty(row) {
1437
1511
  return !("_tombstone" in row);
1438
1512
  }
1439
1513
  function useParties(tripRef) {
1440
- const client$1 = chunkUALMCHNW_cjs.useKaafilClient();
1514
+ const client$1 = chunk3N2EQ2KC_cjs.useKaafilClient();
1441
1515
  const [rows, setRows] = react.useState([]);
1442
1516
  const [listLoaded, setListLoaded] = react.useState(false);
1443
1517
  const [listFetchFailed, setListFetchFailed] = react.useState(false);
@@ -1477,7 +1551,7 @@ function useParties(tripRef) {
1477
1551
  react.useEffect(() => {
1478
1552
  void refreshRoster();
1479
1553
  }, [refreshRoster]);
1480
- const addMutation = chunkUALMCHNW_cjs.useOfflineMutation({
1554
+ const addMutation = chunk3N2EQ2KC_cjs.useOfflineMutation({
1481
1555
  tripRef,
1482
1556
  enqueue: (engine, input) => engine.enqueue({
1483
1557
  tripRef,
@@ -1487,7 +1561,7 @@ function useParties(tripRef) {
1487
1561
  body: input
1488
1562
  })
1489
1563
  });
1490
- const patchMutation = chunkUALMCHNW_cjs.useOfflineMutation({
1564
+ const patchMutation = chunk3N2EQ2KC_cjs.useOfflineMutation({
1491
1565
  tripRef,
1492
1566
  enqueue: (engine, input) => {
1493
1567
  const { partyId, version, ...body } = input;
@@ -1501,7 +1575,7 @@ function useParties(tripRef) {
1501
1575
  });
1502
1576
  }
1503
1577
  });
1504
- const removeMutation = chunkUALMCHNW_cjs.useOfflineMutation({
1578
+ const removeMutation = chunk3N2EQ2KC_cjs.useOfflineMutation({
1505
1579
  tripRef,
1506
1580
  enqueue: (engine, input) => {
1507
1581
  const { partyId } = input;
@@ -1577,8 +1651,36 @@ function useParties(tripRef) {
1577
1651
  remove
1578
1652
  };
1579
1653
  }
1654
+ function optimisticPickupStop(input, syncedAt) {
1655
+ return {
1656
+ // Replaced by the id the engine mints.
1657
+ id: "pending",
1658
+ version: 0,
1659
+ // The request's own default, restated rather than guessed: the SDK's
1660
+ // `kind` is optional and the engine treats an absent one as a pickup.
1661
+ kind: input.kind ?? "PICKUP",
1662
+ name: input.name,
1663
+ locationLabel: input.locationLabel ?? null,
1664
+ lat: input.lat ?? null,
1665
+ lng: input.lng ?? null,
1666
+ scheduledTime: client.normalizeDateTimeInput(input.scheduledTime, "scheduledTime"),
1667
+ // Appended; the server's ordering arrives with the canonical row.
1668
+ sortOrder: input.sortOrder ?? Number.MAX_SAFE_INTEGER,
1669
+ status: "OPEN",
1670
+ closedAt: null,
1671
+ closedByManagerId: null,
1672
+ performedByKind: null,
1673
+ performedById: null,
1674
+ rollup: "not_started",
1675
+ boardedCount: 0,
1676
+ expectedCount: 0,
1677
+ // The last reading the SERVER gave this list, never a device clock
1678
+ // (hard rule #6).
1679
+ updatedAt: syncedAt ?? ""
1680
+ };
1681
+ }
1580
1682
  var usePickupsInternal = createDomainHook("pickup-points", (tripRef) => {
1581
- const client$1 = chunkUALMCHNW_cjs.useKaafilClient();
1683
+ const client$1 = chunk3N2EQ2KC_cjs.useKaafilClient();
1582
1684
  const {
1583
1685
  rows: stops,
1584
1686
  syncedAt,
@@ -1589,7 +1691,7 @@ var usePickupsInternal = createDomainHook("pickup-points", (tripRef) => {
1589
1691
  return { rows: response, syncedAt: response.meta.serverTime };
1590
1692
  }
1591
1693
  });
1592
- const createMutation = chunkUALMCHNW_cjs.useOfflineMutation({
1694
+ const createMutation = chunk3N2EQ2KC_cjs.useOfflineMutation({
1593
1695
  tripRef,
1594
1696
  enqueue: (engine, input) => engine.enqueue({
1595
1697
  tripRef,
@@ -1600,7 +1702,14 @@ var usePickupsInternal = createDomainHook("pickup-points", (tripRef) => {
1600
1702
  // literal below is checked against `kaafil-js/src/generated/
1601
1703
  // security.ts`'s own operation-id table.
1602
1704
  operationId: "createPickupStop",
1603
- body: input
1705
+ body: input,
1706
+ // A stop added out of signal appears at once, keyed on an id the
1707
+ // ENGINE mints and swapped for the server's row when the write lands
1708
+ // — see `optimisticPickupStop` for why every field here is one the
1709
+ // client can honestly know.
1710
+ creates: true,
1711
+ entity: { listName: "pickups" },
1712
+ optimistic: optimisticPickupStop(input, syncedAt)
1604
1713
  }),
1605
1714
  // The desk lane. `board`, `close` and `reopen` below deliberately get
1606
1715
  // NONE — they are `managerAuth`-only on the wire, so a direct call from
@@ -1608,7 +1717,7 @@ var usePickupsInternal = createDomainHook("pickup-points", (tripRef) => {
1608
1717
  // before it left the process. See this file's own persona note.
1609
1718
  direct: (liveClient, input) => liveClient.pickups.create({ tripRef, ...input })
1610
1719
  });
1611
- const patchMutation = chunkUALMCHNW_cjs.useOfflineMutation({
1720
+ const patchMutation = chunk3N2EQ2KC_cjs.useOfflineMutation({
1612
1721
  tripRef,
1613
1722
  enqueue: (engine, input) => {
1614
1723
  const { pointId, version, ...body } = input;
@@ -1623,7 +1732,7 @@ var usePickupsInternal = createDomainHook("pickup-points", (tripRef) => {
1623
1732
  },
1624
1733
  direct: (liveClient, input) => liveClient.pickups.patch({ tripRef, ...input })
1625
1734
  });
1626
- const removeMutation = chunkUALMCHNW_cjs.useOfflineMutation({
1735
+ const removeMutation = chunk3N2EQ2KC_cjs.useOfflineMutation({
1627
1736
  tripRef,
1628
1737
  enqueue: (engine, input) => {
1629
1738
  const { pointId, version, force } = input;
@@ -1638,7 +1747,7 @@ var usePickupsInternal = createDomainHook("pickup-points", (tripRef) => {
1638
1747
  },
1639
1748
  direct: (liveClient, input) => liveClient.pickups.remove({ tripRef, ...input })
1640
1749
  });
1641
- const reorderMutation = chunkUALMCHNW_cjs.useOfflineMutation({
1750
+ const reorderMutation = chunk3N2EQ2KC_cjs.useOfflineMutation({
1642
1751
  tripRef,
1643
1752
  enqueue: (engine, input) => engine.enqueue({
1644
1753
  tripRef,
@@ -1649,7 +1758,7 @@ var usePickupsInternal = createDomainHook("pickup-points", (tripRef) => {
1649
1758
  }),
1650
1759
  direct: (liveClient, input) => liveClient.pickups.reorder({ tripRef, ...input })
1651
1760
  });
1652
- const assignMutation = chunkUALMCHNW_cjs.useOfflineMutation({
1761
+ const assignMutation = chunk3N2EQ2KC_cjs.useOfflineMutation({
1653
1762
  tripRef,
1654
1763
  enqueue: (engine, input) => {
1655
1764
  const { pointId, ...body } = input;
@@ -1663,7 +1772,7 @@ var usePickupsInternal = createDomainHook("pickup-points", (tripRef) => {
1663
1772
  },
1664
1773
  direct: (liveClient, input) => liveClient.pickups.assign({ tripRef, ...input })
1665
1774
  });
1666
- const boardMutation = chunkUALMCHNW_cjs.useOfflineMutation({
1775
+ const boardMutation = chunk3N2EQ2KC_cjs.useOfflineMutation({
1667
1776
  tripRef,
1668
1777
  enqueue: (engine, input) => {
1669
1778
  const { pointId, ...body } = input;
@@ -1676,7 +1785,7 @@ var usePickupsInternal = createDomainHook("pickup-points", (tripRef) => {
1676
1785
  });
1677
1786
  }
1678
1787
  });
1679
- const correctBoardStatusMutation = chunkUALMCHNW_cjs.useOfflineMutation({
1788
+ const correctBoardStatusMutation = chunk3N2EQ2KC_cjs.useOfflineMutation({
1680
1789
  tripRef,
1681
1790
  enqueue: (engine, input) => {
1682
1791
  const { pointId, travellerId, ...body } = input;
@@ -1693,7 +1802,7 @@ var usePickupsInternal = createDomainHook("pickup-points", (tripRef) => {
1693
1802
  // still get none, because they are `managerAuth`-only.
1694
1803
  direct: (liveClient, input) => liveClient.pickups.correctBoardStatus({ tripRef, ...input })
1695
1804
  });
1696
- const closeMutation = chunkUALMCHNW_cjs.useOfflineMutation({
1805
+ const closeMutation = chunk3N2EQ2KC_cjs.useOfflineMutation({
1697
1806
  tripRef,
1698
1807
  enqueue: (engine, input) => {
1699
1808
  const { pointId, ...body } = input;
@@ -1706,7 +1815,7 @@ var usePickupsInternal = createDomainHook("pickup-points", (tripRef) => {
1706
1815
  });
1707
1816
  }
1708
1817
  });
1709
- const reopenMutation = chunkUALMCHNW_cjs.useOfflineMutation({
1818
+ const reopenMutation = chunk3N2EQ2KC_cjs.useOfflineMutation({
1710
1819
  tripRef,
1711
1820
  enqueue: (engine, input) => {
1712
1821
  const { pointId } = input;
@@ -1746,8 +1855,26 @@ var usePickupsInternal = createDomainHook("pickup-points", (tripRef) => {
1746
1855
  function usePickups(tripRef) {
1747
1856
  return usePickupsInternal(tripRef);
1748
1857
  }
1858
+ function optimisticStayWindow(input, syncedAt) {
1859
+ return {
1860
+ // Replaced by the id the engine mints.
1861
+ id: "pending",
1862
+ version: 0,
1863
+ label: input.label,
1864
+ startDate: client.normalizeDateTimeInput(input.startDate, "startDate"),
1865
+ endDate: client.normalizeDateTimeInput(input.endDate, "endDate"),
1866
+ // Appended; the server's ordering arrives with the canonical row.
1867
+ sortOrder: input.sortOrder ?? Number.MAX_SAFE_INTEGER,
1868
+ // A window created by hand has no CRM segment behind it. This is a fact
1869
+ // about the write, not a placeholder.
1870
+ sourceSegmentRef: null,
1871
+ sourceUpdatedAt: null,
1872
+ // The last reading the SERVER gave this list, never a device clock.
1873
+ updatedAt: syncedAt ?? ""
1874
+ };
1875
+ }
1749
1876
  var useRoomingInternal = createDomainHook("rooming", (tripRef) => {
1750
- const client$1 = chunkUALMCHNW_cjs.useKaafilClient();
1877
+ const client$1 = chunk3N2EQ2KC_cjs.useKaafilClient();
1751
1878
  const {
1752
1879
  rows: rooms,
1753
1880
  syncedAt: roomsSyncedAt,
@@ -1771,9 +1898,9 @@ var useRoomingInternal = createDomainHook("rooming", (tripRef) => {
1771
1898
  const refreshLive = react.useCallback(async () => {
1772
1899
  await Promise.all([refreshRoomsLive(), refreshWindowsLive()]);
1773
1900
  }, [refreshRoomsLive, refreshWindowsLive]);
1774
- const assignMutation = chunkUALMCHNW_cjs.useOfflineMutation({
1901
+ const assignMutation = chunk3N2EQ2KC_cjs.useOfflineMutation({
1775
1902
  tripRef,
1776
- enqueue: (engine, input) => engine.enqueue({
1903
+ enqueue: (engine2, input) => engine2.enqueue({
1777
1904
  tripRef,
1778
1905
  method: client.SyncOpMethod.Post,
1779
1906
  path: `/api/v1/trips/${tripRef}/rooming/assign`,
@@ -1817,6 +1944,16 @@ var useRoomingInternal = createDomainHook("rooming", (tripRef) => {
1817
1944
  react.useEffect(() => {
1818
1945
  void refreshUnassignedPool();
1819
1946
  }, [refreshUnassignedPool]);
1947
+ const engine = react.useContext(chunk3N2EQ2KC_cjs.OfflineEngineContext);
1948
+ react.useEffect(() => {
1949
+ if (engine === null) {
1950
+ return;
1951
+ }
1952
+ const unsubscribe = engine.events.on("sync.drained", () => {
1953
+ void refreshUnassignedPool(lastRequestedStayWindowIdRef.current);
1954
+ });
1955
+ return unsubscribe;
1956
+ }, [engine, refreshUnassignedPool]);
1820
1957
  const assignMutate = assignMutation.mutate;
1821
1958
  const assign = react.useCallback(
1822
1959
  async (input) => {
@@ -1826,22 +1963,29 @@ var useRoomingInternal = createDomainHook("rooming", (tripRef) => {
1826
1963
  },
1827
1964
  [assignMutate, refreshUnassignedPool]
1828
1965
  );
1829
- const createWindowMutation = chunkUALMCHNW_cjs.useOfflineMutation({
1966
+ const createWindowMutation = chunk3N2EQ2KC_cjs.useOfflineMutation({
1830
1967
  tripRef,
1831
- enqueue: (engine, input) => engine.enqueue({
1968
+ enqueue: (engine2, input) => engine2.enqueue({
1832
1969
  tripRef,
1833
1970
  method: client.SyncOpMethod.Post,
1834
1971
  path: `/api/v1/trips/${tripRef}/rooming/stay-windows`,
1835
1972
  operationId: "createRoomingStayWindow",
1836
- body: input
1973
+ body: input,
1974
+ // A window added out of signal appears at once. Every field of a
1975
+ // stay window is either given by the caller or genuinely absent —
1976
+ // which is exactly what `createRoom` below cannot say, and why only
1977
+ // this one of the two gets an optimistic row.
1978
+ creates: true,
1979
+ entity: { listName: "stayWindows" },
1980
+ optimistic: optimisticStayWindow(input, windowsSyncedAt)
1837
1981
  }),
1838
1982
  direct: (liveClient, input) => liveClient.rooming.stayWindows.create({ tripRef, ...input })
1839
1983
  });
1840
- const patchWindowMutation = chunkUALMCHNW_cjs.useOfflineMutation({
1984
+ const patchWindowMutation = chunk3N2EQ2KC_cjs.useOfflineMutation({
1841
1985
  tripRef,
1842
- enqueue: (engine, input) => {
1986
+ enqueue: (engine2, input) => {
1843
1987
  const { windowId, version, ...body } = input;
1844
- return engine.enqueue({
1988
+ return engine2.enqueue({
1845
1989
  tripRef,
1846
1990
  method: client.SyncOpMethod.Patch,
1847
1991
  path: `/api/v1/trips/${tripRef}/rooming/stay-windows/${windowId}`,
@@ -1852,12 +1996,12 @@ var useRoomingInternal = createDomainHook("rooming", (tripRef) => {
1852
1996
  },
1853
1997
  direct: (liveClient, input) => liveClient.rooming.stayWindows.patch({ tripRef, ...input })
1854
1998
  });
1855
- const removeWindowMutation = chunkUALMCHNW_cjs.useOfflineMutation({
1999
+ const removeWindowMutation = chunk3N2EQ2KC_cjs.useOfflineMutation({
1856
2000
  tripRef,
1857
- enqueue: (engine, input) => {
2001
+ enqueue: (engine2, input) => {
1858
2002
  const { windowId, version, force } = input;
1859
2003
  const query = force === true ? "?force=true" : "";
1860
- return engine.enqueue({
2004
+ return engine2.enqueue({
1861
2005
  tripRef,
1862
2006
  method: client.SyncOpMethod.Delete,
1863
2007
  path: `/api/v1/trips/${tripRef}/rooming/stay-windows/${windowId}${query}`,
@@ -1867,9 +2011,9 @@ var useRoomingInternal = createDomainHook("rooming", (tripRef) => {
1867
2011
  },
1868
2012
  direct: (liveClient, input) => liveClient.rooming.stayWindows.remove({ tripRef, ...input })
1869
2013
  });
1870
- const createRoomMutation = chunkUALMCHNW_cjs.useOfflineMutation({
2014
+ const createRoomMutation = chunk3N2EQ2KC_cjs.useOfflineMutation({
1871
2015
  tripRef,
1872
- enqueue: (engine, input) => engine.enqueue({
2016
+ enqueue: (engine2, input) => engine2.enqueue({
1873
2017
  tripRef,
1874
2018
  method: client.SyncOpMethod.Post,
1875
2019
  path: `/api/v1/trips/${tripRef}/rooming/rooms`,
@@ -1878,11 +2022,11 @@ var useRoomingInternal = createDomainHook("rooming", (tripRef) => {
1878
2022
  }),
1879
2023
  direct: (liveClient, input) => liveClient.rooming.rooms.create({ tripRef, ...input })
1880
2024
  });
1881
- const patchRoomMutation = chunkUALMCHNW_cjs.useOfflineMutation({
2025
+ const patchRoomMutation = chunk3N2EQ2KC_cjs.useOfflineMutation({
1882
2026
  tripRef,
1883
- enqueue: (engine, input) => {
2027
+ enqueue: (engine2, input) => {
1884
2028
  const { roomId, version, ...body } = input;
1885
- return engine.enqueue({
2029
+ return engine2.enqueue({
1886
2030
  tripRef,
1887
2031
  method: client.SyncOpMethod.Patch,
1888
2032
  path: `/api/v1/trips/${tripRef}/rooming/rooms/${roomId}`,
@@ -1893,12 +2037,12 @@ var useRoomingInternal = createDomainHook("rooming", (tripRef) => {
1893
2037
  },
1894
2038
  direct: (liveClient, input) => liveClient.rooming.rooms.patch({ tripRef, ...input })
1895
2039
  });
1896
- const removeRoomMutation = chunkUALMCHNW_cjs.useOfflineMutation({
2040
+ const removeRoomMutation = chunk3N2EQ2KC_cjs.useOfflineMutation({
1897
2041
  tripRef,
1898
- enqueue: (engine, input) => {
2042
+ enqueue: (engine2, input) => {
1899
2043
  const { roomId, version, force } = input;
1900
2044
  const query = force === true ? "?force=true" : "";
1901
- return engine.enqueue({
2045
+ return engine2.enqueue({
1902
2046
  tripRef,
1903
2047
  method: client.SyncOpMethod.Delete,
1904
2048
  path: `/api/v1/trips/${tripRef}/rooming/rooms/${roomId}${query}`,
@@ -1939,7 +2083,7 @@ function useRooming(tripRef) {
1939
2083
  return useRoomingInternal(tripRef);
1940
2084
  }
1941
2085
  var useSeatingInternal = createDomainHook("transport-seating", (tripRef) => {
1942
- const client$1 = chunkUALMCHNW_cjs.useKaafilClient();
2086
+ const client$1 = chunk3N2EQ2KC_cjs.useKaafilClient();
1943
2087
  const {
1944
2088
  rows: vehicles,
1945
2089
  syncedAt,
@@ -1950,9 +2094,9 @@ var useSeatingInternal = createDomainHook("transport-seating", (tripRef) => {
1950
2094
  return { rows: response.vehicles, syncedAt: response.meta.serverTime };
1951
2095
  }
1952
2096
  });
1953
- const assignMutation = chunkUALMCHNW_cjs.useOfflineMutation({
2097
+ const assignMutation = chunk3N2EQ2KC_cjs.useOfflineMutation({
1954
2098
  tripRef,
1955
- enqueue: (engine, input) => engine.enqueue({
2099
+ enqueue: (engine2, input) => engine2.enqueue({
1956
2100
  tripRef,
1957
2101
  method: client.SyncOpMethod.Post,
1958
2102
  path: `/api/v1/trips/${tripRef}/seating/assign`,
@@ -1989,6 +2133,16 @@ var useSeatingInternal = createDomainHook("transport-seating", (tripRef) => {
1989
2133
  react.useEffect(() => {
1990
2134
  void refreshUnassignedPool();
1991
2135
  }, [refreshUnassignedPool]);
2136
+ const engine = react.useContext(chunk3N2EQ2KC_cjs.OfflineEngineContext);
2137
+ react.useEffect(() => {
2138
+ if (engine === null) {
2139
+ return;
2140
+ }
2141
+ const unsubscribe = engine.events.on("sync.drained", () => {
2142
+ void refreshUnassignedPool();
2143
+ });
2144
+ return unsubscribe;
2145
+ }, [engine, refreshUnassignedPool]);
1992
2146
  const assignMutate = assignMutation.mutate;
1993
2147
  const assign = react.useCallback(
1994
2148
  async (input) => {
@@ -1998,9 +2152,9 @@ var useSeatingInternal = createDomainHook("transport-seating", (tripRef) => {
1998
2152
  },
1999
2153
  [assignMutate, refreshUnassignedPool]
2000
2154
  );
2001
- const createVehicleMutation = chunkUALMCHNW_cjs.useOfflineMutation({
2155
+ const createVehicleMutation = chunk3N2EQ2KC_cjs.useOfflineMutation({
2002
2156
  tripRef,
2003
- enqueue: (engine, input) => engine.enqueue({
2157
+ enqueue: (engine2, input) => engine2.enqueue({
2004
2158
  tripRef,
2005
2159
  method: client.SyncOpMethod.Post,
2006
2160
  path: `/api/v1/trips/${tripRef}/seating/vehicles`,
@@ -2009,11 +2163,11 @@ var useSeatingInternal = createDomainHook("transport-seating", (tripRef) => {
2009
2163
  }),
2010
2164
  direct: (liveClient, input) => liveClient.seating.vehicles.create({ tripRef, ...input })
2011
2165
  });
2012
- const patchVehicleMutation = chunkUALMCHNW_cjs.useOfflineMutation({
2166
+ const patchVehicleMutation = chunk3N2EQ2KC_cjs.useOfflineMutation({
2013
2167
  tripRef,
2014
- enqueue: (engine, input) => {
2168
+ enqueue: (engine2, input) => {
2015
2169
  const { vehicleId, version, ...body } = input;
2016
- return engine.enqueue({
2170
+ return engine2.enqueue({
2017
2171
  tripRef,
2018
2172
  method: client.SyncOpMethod.Patch,
2019
2173
  path: `/api/v1/trips/${tripRef}/seating/vehicles/${vehicleId}`,
@@ -2024,11 +2178,11 @@ var useSeatingInternal = createDomainHook("transport-seating", (tripRef) => {
2024
2178
  },
2025
2179
  direct: (liveClient, input) => liveClient.seating.vehicles.patch({ tripRef, ...input })
2026
2180
  });
2027
- const removeVehicleMutation = chunkUALMCHNW_cjs.useOfflineMutation({
2181
+ const removeVehicleMutation = chunk3N2EQ2KC_cjs.useOfflineMutation({
2028
2182
  tripRef,
2029
- enqueue: (engine, input) => {
2183
+ enqueue: (engine2, input) => {
2030
2184
  const { vehicleId, version } = input;
2031
- return engine.enqueue({
2185
+ return engine2.enqueue({
2032
2186
  tripRef,
2033
2187
  method: client.SyncOpMethod.Delete,
2034
2188
  path: `/api/v1/trips/${tripRef}/seating/vehicles/${vehicleId}`,
@@ -2066,11 +2220,11 @@ var useSeatingInternal = createDomainHook("transport-seating", (tripRef) => {
2066
2220
  },
2067
2221
  [patchVehicleMutate, vehicles]
2068
2222
  );
2069
- const linkManagerMutation = chunkUALMCHNW_cjs.useOfflineMutation({
2223
+ const linkManagerMutation = chunk3N2EQ2KC_cjs.useOfflineMutation({
2070
2224
  tripRef,
2071
- enqueue: (engine, input) => {
2225
+ enqueue: (engine2, input) => {
2072
2226
  const { vehicleId, ...body } = input;
2073
- return engine.enqueue({
2227
+ return engine2.enqueue({
2074
2228
  tripRef,
2075
2229
  method: client.SyncOpMethod.Post,
2076
2230
  path: `/api/v1/trips/${tripRef}/seating/vehicles/${vehicleId}/manager`,
@@ -2080,11 +2234,11 @@ var useSeatingInternal = createDomainHook("transport-seating", (tripRef) => {
2080
2234
  },
2081
2235
  direct: (liveClient, input) => liveClient.seating.vehicles.manager.link({ tripRef, ...input })
2082
2236
  });
2083
- const unlinkManagerMutation = chunkUALMCHNW_cjs.useOfflineMutation({
2237
+ const unlinkManagerMutation = chunk3N2EQ2KC_cjs.useOfflineMutation({
2084
2238
  tripRef,
2085
- enqueue: (engine, input) => {
2239
+ enqueue: (engine2, input) => {
2086
2240
  const { vehicleId, version } = input;
2087
- return engine.enqueue({
2241
+ return engine2.enqueue({
2088
2242
  tripRef,
2089
2243
  method: client.SyncOpMethod.Delete,
2090
2244
  path: `/api/v1/trips/${tripRef}/seating/vehicles/${vehicleId}/manager`,
@@ -2123,7 +2277,7 @@ function useSeating(tripRef) {
2123
2277
  return useSeatingInternal(tripRef);
2124
2278
  }
2125
2279
  function useTravellerProfile(tripRef, travellerRef) {
2126
- const client$1 = chunkUALMCHNW_cjs.useKaafilClient();
2280
+ const client$1 = chunk3N2EQ2KC_cjs.useKaafilClient();
2127
2281
  const [read, setRead] = react.useState(void 0);
2128
2282
  const [readFailed, setReadFailed] = react.useState(false);
2129
2283
  const refresh = react.useCallback(async () => {
@@ -2138,8 +2292,8 @@ function useTravellerProfile(tripRef, travellerRef) {
2138
2292
  react.useEffect(() => {
2139
2293
  void refresh();
2140
2294
  }, [refresh]);
2141
- chunkUALMCHNW_cjs.useOfflineEvent("sync.drained", refresh);
2142
- const noteMutation = chunkUALMCHNW_cjs.useOfflineMutation({
2295
+ chunk3N2EQ2KC_cjs.useOfflineEvent("sync.drained", refresh);
2296
+ const noteMutation = chunk3N2EQ2KC_cjs.useOfflineMutation({
2143
2297
  tripRef,
2144
2298
  enqueue: (engine, input) => engine.enqueue({
2145
2299
  tripRef,
@@ -2161,8 +2315,8 @@ function useTravellerProfile(tripRef, travellerRef) {
2161
2315
  return { read, readFailed, refresh, addNote };
2162
2316
  }
2163
2317
  function useVendors(tripRef, agencyRef) {
2164
- const client = chunkUALMCHNW_cjs.useKaafilClient();
2165
- const { rows, loaded: capabilitiesLoaded } = chunkUALMCHNW_cjs.useCapabilityRows(tripRef);
2318
+ const client = chunk3N2EQ2KC_cjs.useKaafilClient();
2319
+ const { rows, loaded: capabilitiesLoaded } = chunk3N2EQ2KC_cjs.useCapabilityRows(tripRef);
2166
2320
  const [vendors, setVendors] = react.useState([]);
2167
2321
  const [listLoaded, setListLoaded] = react.useState(false);
2168
2322
  const [lastFetchFailed, setLastFetchFailed] = react.useState(false);
@@ -2191,9 +2345,9 @@ function useVendors(tripRef, agencyRef) {
2191
2345
  return { status: "loading" };
2192
2346
  }
2193
2347
  const row = rows.find((candidate) => candidate.capability === "vendors");
2194
- const triple = row === void 0 ? chunkUALMCHNW_cjs.UNKNOWN_CAPABILITY_TRIPLE : chunkUALMCHNW_cjs.deriveCapabilityTriple(row);
2348
+ const triple = row === void 0 ? chunk3N2EQ2KC_cjs.UNKNOWN_CAPABILITY_TRIPLE : chunk3N2EQ2KC_cjs.deriveCapabilityTriple(row);
2195
2349
  if (triple.status !== "lit") {
2196
- const reason = chunkUALMCHNW_cjs.darkReasonFor(triple);
2350
+ const reason = chunk3N2EQ2KC_cjs.darkReasonFor(triple);
2197
2351
  return { status: "dark", reason };
2198
2352
  }
2199
2353
  if (!listLoaded && lastFetchFailed) {
@@ -2262,5 +2416,5 @@ exports.useSeating = useSeating;
2262
2416
  exports.useSnapshotList = useSnapshotList;
2263
2417
  exports.useTravellerProfile = useTravellerProfile;
2264
2418
  exports.useVendors = useVendors;
2265
- //# sourceMappingURL=chunk-MNUCVVIE.cjs.map
2266
- //# sourceMappingURL=chunk-MNUCVVIE.cjs.map
2419
+ //# sourceMappingURL=chunk-A7C74SJT.cjs.map
2420
+ //# sourceMappingURL=chunk-A7C74SJT.cjs.map