@teincfood/core 0.10.23 → 0.10.24

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.
@@ -19,6 +19,10 @@ import { getConnectivityState } from "../adapters/connectivity";
19
19
  import { CAPABILITY_BY_COMMAND } from "../reference/capabilities";
20
20
  import { openSyncDatabase } from "../db/connection";
21
21
  import { getReferenceData } from "../reference/operations";
22
+ import { commandQueueService } from "./command-queue.service";
23
+ import { applyMenuCommandLocal } from "../reference/menu-apply";
24
+ import { emitReferenceChanged } from "../reference/events";
25
+ import { isOnlineCapable } from "./online-gates";
22
26
  export async function runOfflineCapableMutation(options) {
23
27
  // Per-command capability guard before even attempting direct call
24
28
  const required = CAPABILITY_BY_COMMAND[options.commandType];
@@ -26,10 +30,10 @@ export async function runOfflineCapableMutation(options) {
26
30
  // Online-required gate first: these commands can never succeed offline —
27
31
  // throw loud immediately instead of queuing what no transport can fulfill.
28
32
  assertOnlineFor(options.commandType, options.payload);
29
- // Local-first for engine-routed domains (menu:*): commit locally via the
30
- // engine and resolve immediately. Network is sync transport only — never a
31
- // mutation delay. The engine cloud path carries the same 2.5s cap and
32
- // returns the backend response when online.
33
+ // Local-first for engine-routed domains (menu:*): persist to SQLite and the
34
+ // durable outbox immediately, update the local reference cache, and let
35
+ // replay upload to the cloud/LAN in the background. A slow or absent
36
+ // network must never hold the form open.
33
37
  if (options.commandType.startsWith("menu:")) {
34
38
  const command = buildCommand({
35
39
  commandType: options.commandType,
@@ -37,8 +41,26 @@ export async function runOfflineCapableMutation(options) {
37
41
  entityId: options.entityId,
38
42
  payload: options.payload,
39
43
  });
40
- const events = await syncEngine.execute(command);
41
- return events[0]?.payload;
44
+ try {
45
+ const { keys } = await applyMenuCommandLocal(options.businessId, command);
46
+ if (keys.length)
47
+ emitReferenceChanged(options.businessId, keys);
48
+ }
49
+ catch (error) {
50
+ syncLogger.debug("OfflineCapable", "menu local apply failed", {
51
+ error: String(error),
52
+ });
53
+ }
54
+ const event = await commandQueueService.enqueue(command);
55
+ if (isOnlineCapable()) {
56
+ // Background only: save must return now.
57
+ void syncEngine.replayQueuedCommands().catch((error) => {
58
+ syncLogger.debug("OfflineCapable", "menu background replay failed", {
59
+ error: String(error),
60
+ });
61
+ });
62
+ }
63
+ return event.payload;
42
64
  }
43
65
  try {
44
66
  const db = await openSyncDatabase();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@teincfood/core",
3
- "version": "0.10.23",
3
+ "version": "0.10.24",
4
4
  "description": "TeincFood shared offline-first core — types, sync engine, local DB, reference data, and repositories for mobile + desktop",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",