@teincfood/core 0.1.1 → 0.1.3

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 (72) hide show
  1. package/dist/adapters/auth.js +2 -6
  2. package/dist/adapters/business.js +2 -6
  3. package/dist/adapters/connectivity.js +6 -14
  4. package/dist/adapters/devices.js +2 -6
  5. package/dist/adapters/http.js +4 -10
  6. package/dist/adapters/image-cache.d.ts +9 -3
  7. package/dist/adapters/image-cache.js +12 -8
  8. package/dist/adapters/kv-types.js +1 -2
  9. package/dist/adapters/kv.js +11 -24
  10. package/dist/adapters/local-node.js +3 -7
  11. package/dist/adapters/pending-orders.js +1 -4
  12. package/dist/adapters/query-keys.js +4 -7
  13. package/dist/adapters/services.js +9 -14
  14. package/dist/adapters/sqlite.js +3 -8
  15. package/dist/db/connection.js +15 -20
  16. package/dist/db/migrations.js +1 -4
  17. package/dist/db/operations.js +19 -36
  18. package/dist/index.d.ts +3 -0
  19. package/dist/index.js +43 -93
  20. package/dist/reference/api.js +7 -12
  21. package/dist/reference/events.js +25 -33
  22. package/dist/reference/operations.js +6 -14
  23. package/dist/reference/service.js +36 -39
  24. package/dist/reference/types.js +1 -2
  25. package/dist/repositories/order.repository.js +15 -18
  26. package/dist/repositories/pos.repository.js +6 -9
  27. package/dist/sync/command-builder.js +8 -12
  28. package/dist/sync/command-queue.service.js +35 -38
  29. package/dist/sync/engine.js +38 -42
  30. package/dist/sync/order-number.js +6 -11
  31. package/dist/sync/order-number.test.d.ts +1 -0
  32. package/dist/sync/order-number.test.js +30 -0
  33. package/dist/sync/order-snapshots.service.js +19 -22
  34. package/dist/sync/pending-orders.service.js +27 -33
  35. package/dist/sync/transport-local-node.js +16 -20
  36. package/dist/sync/transport-rest.js +18 -22
  37. package/dist/sync/types.js +1 -2
  38. package/dist/sync/use-sync-reconciliation.js +37 -40
  39. package/dist/types/api/auth.api.js +1 -2
  40. package/dist/types/api/business.api.js +1 -2
  41. package/dist/types/api/conversation.api.js +1 -2
  42. package/dist/types/api/error.api.js +1 -2
  43. package/dist/types/api/fleet.api.js +1 -2
  44. package/dist/types/api/index.js +11 -27
  45. package/dist/types/api/kiosk.api.js +1 -2
  46. package/dist/types/api/menu.api.js +1 -2
  47. package/dist/types/api/pagination.js +1 -2
  48. package/dist/types/api/rider.api.js +1 -2
  49. package/dist/types/api/seller.api.js +1 -2
  50. package/dist/types/api/wallet.api.js +1 -2
  51. package/dist/types/pos.types.js +1 -2
  52. package/dist/utils/constants.js +24 -27
  53. package/dist/utils/copyToClipBoard.js +2 -7
  54. package/dist/utils/currency.js +8 -16
  55. package/dist/utils/currency.test.d.ts +1 -0
  56. package/dist/utils/currency.test.js +17 -0
  57. package/dist/utils/error.js +4 -11
  58. package/dist/utils/formatCurrency.js +1 -4
  59. package/dist/utils/formatDate.js +2 -6
  60. package/dist/utils/phone.js +6 -13
  61. package/dist/utils/phone.test.d.ts +1 -0
  62. package/dist/utils/phone.test.js +19 -0
  63. package/dist/utils/responsive.js +1 -4
  64. package/dist/utils/storage.js +14 -28
  65. package/dist/utils/sync-logger.js +1 -4
  66. package/dist/utils/uuid.js +4 -10
  67. package/dist/utils/uuid.test.d.ts +1 -0
  68. package/dist/utils/uuid.test.js +13 -0
  69. package/dist/utils/validation.js +11 -24
  70. package/dist/utils/validation.test.d.ts +1 -0
  71. package/dist/utils/validation.test.js +23 -0
  72. package/package.json +16 -1
@@ -1,4 +1,3 @@
1
- "use strict";
2
1
  /**
3
2
  * Reference Data Synchronization Service.
4
3
  *
@@ -8,15 +7,13 @@
8
7
  * This service is separate from the Sync Engine, which handles transactional
9
8
  * commands and events.
10
9
  */
11
- Object.defineProperty(exports, "__esModule", { value: true });
12
- exports.referenceSyncService = void 0;
13
- const connection_1 = require("../db/connection");
14
- const sync_logger_1 = require("../utils/sync-logger");
15
- const uuid_1 = require("../utils/uuid");
16
- const services_1 = require("../adapters/services");
17
- const image_cache_1 = require("../adapters/image-cache");
18
- const operations_1 = require("./operations");
19
- const api_1 = require("./api");
10
+ import { openSyncDatabase } from "../db/connection";
11
+ import { syncLogger } from "../utils/sync-logger";
12
+ import { generateUUID } from "../utils/uuid";
13
+ import { menuService, businessService, rolesService } from "../adapters/services";
14
+ import { cacheImageBatch, pruneImageCache } from "../adapters/image-cache";
15
+ import { getReferenceData, getReferenceVersion, setReferenceData, } from "./operations";
16
+ import { fetchReferenceVersions, fetchReferenceData, fetchReferenceChanges, } from "./api";
20
17
  const DEFAULT_SYNC_KEYS = [
21
18
  "menu:items",
22
19
  "menu:categories",
@@ -41,7 +38,7 @@ class ReferenceSyncService {
41
38
  };
42
39
  }
43
40
  this.isSyncing = true;
44
- sync_logger_1.syncLogger.info("ReferenceSync", "Starting reference data sync", {
41
+ syncLogger.info("ReferenceSync", "Starting reference data sync", {
45
42
  businessId: options.businessId,
46
43
  keys: options.keys,
47
44
  });
@@ -52,16 +49,16 @@ class ReferenceSyncService {
52
49
  errors: {},
53
50
  };
54
51
  try {
55
- const db = await (0, connection_1.openSyncDatabase)();
52
+ const db = await openSyncDatabase();
56
53
  const keys = options.keys ?? DEFAULT_SYNC_KEYS;
57
54
  // Attempt version-aware sync. If the backend does not support versioning
58
55
  // endpoints, fall back to legacy full-fetch per key.
59
56
  let versions = null;
60
57
  try {
61
- versions = await (0, api_1.fetchReferenceVersions)(options.businessId);
58
+ versions = await fetchReferenceVersions(options.businessId);
62
59
  }
63
60
  catch (error) {
64
- sync_logger_1.syncLogger.warn("ReferenceSync", "Version endpoint unavailable, using fallback", {
61
+ syncLogger.warn("ReferenceSync", "Version endpoint unavailable, using fallback", {
65
62
  error: String(error),
66
63
  });
67
64
  }
@@ -78,7 +75,7 @@ class ReferenceSyncService {
78
75
  catch (error) {
79
76
  result.failed.push(key);
80
77
  result.errors[key] = String(error);
81
- sync_logger_1.syncLogger.error("ReferenceSync", `Failed to sync ${key}`, {
78
+ syncLogger.error("ReferenceSync", `Failed to sync ${key}`, {
82
79
  error: String(error),
83
80
  });
84
81
  }
@@ -93,7 +90,7 @@ class ReferenceSyncService {
93
90
  finally {
94
91
  this.isSyncing = false;
95
92
  }
96
- sync_logger_1.syncLogger.info("ReferenceSync", "Reference data sync complete", {
93
+ syncLogger.info("ReferenceSync", "Reference data sync complete", {
97
94
  synced: result.synced,
98
95
  skipped: result.skipped,
99
96
  failed: result.failed,
@@ -102,7 +99,7 @@ class ReferenceSyncService {
102
99
  }
103
100
  async syncKey(db, key, options, versions) {
104
101
  const { businessId } = options;
105
- const localVersion = await (0, operations_1.getReferenceVersion)(db, businessId, key);
102
+ const localVersion = await getReferenceVersion(db, businessId, key);
106
103
  // A key the backend does not version (e.g. during a gradual rollout) is
107
104
  // fetched with a full fetch + local hash so it is still cached offline.
108
105
  const serverVersion = versions?.find((v) => v.key === key)?.version;
@@ -110,7 +107,7 @@ class ReferenceSyncService {
110
107
  // In non-incremental mode without force, we still re-sync if version
111
108
  // info says there is a newer version on the server.
112
109
  if (serverVersion && serverVersion === localVersion) {
113
- sync_logger_1.syncLogger.debug("ReferenceSync", `Up to date: ${key}`, {
110
+ syncLogger.debug("ReferenceSync", `Up to date: ${key}`, {
114
111
  version: localVersion,
115
112
  });
116
113
  return false;
@@ -121,19 +118,19 @@ class ReferenceSyncService {
121
118
  if (versions && serverVersion) {
122
119
  if (localVersion && serverVersion !== localVersion) {
123
120
  try {
124
- const changeSet = await (0, api_1.fetchReferenceChanges)(businessId, key, localVersion);
121
+ const changeSet = await fetchReferenceChanges(businessId, key, localVersion);
125
122
  payload = changeSet.changes;
126
123
  version = changeSet.to_version;
127
124
  }
128
125
  catch {
129
126
  // Fall back to full fetch if changes endpoint fails.
130
- const data = await (0, api_1.fetchReferenceData)(businessId, [key]);
127
+ const data = await fetchReferenceData(businessId, [key]);
131
128
  payload = data[key];
132
129
  version = serverVersion;
133
130
  }
134
131
  }
135
132
  else {
136
- const data = await (0, api_1.fetchReferenceData)(businessId, [key]);
133
+ const data = await fetchReferenceData(businessId, [key]);
137
134
  payload = data[key];
138
135
  version = serverVersion;
139
136
  }
@@ -145,12 +142,12 @@ class ReferenceSyncService {
145
142
  payload = fallback.payload;
146
143
  version = fallback.version;
147
144
  }
148
- await (0, operations_1.setReferenceData)(db, businessId, {
145
+ await setReferenceData(db, businessId, {
149
146
  key,
150
147
  // Defensive: never write a NULL version. If the backend ever omits the
151
148
  // version, generate one so the row is still usable; the next version
152
149
  // comparison will simply see a mismatch and re-sync.
153
- version: version ?? (0, uuid_1.generateUUID)(),
150
+ version: version ?? generateUUID(),
154
151
  payload,
155
152
  downloadedAt: new Date().toISOString(),
156
153
  });
@@ -159,49 +156,49 @@ class ReferenceSyncService {
159
156
  async fetchFallback(key, businessId) {
160
157
  switch (key) {
161
158
  case "menu:items": {
162
- const response = await services_1.menuService.fetchBusinessMenuItems(businessId, 1);
159
+ const response = await menuService.fetchBusinessMenuItems(businessId, 1);
163
160
  return {
164
161
  payload: response,
165
162
  version: this.hashPayload(response),
166
163
  };
167
164
  }
168
165
  case "menu:categories": {
169
- const response = await services_1.menuService.fetchBusinessCategories(businessId);
166
+ const response = await menuService.fetchBusinessCategories(businessId);
170
167
  return {
171
168
  payload: response,
172
169
  version: this.hashPayload(response),
173
170
  };
174
171
  }
175
172
  case "roles": {
176
- const response = await services_1.rolesService.fetchBusinessRoles();
173
+ const response = await rolesService.fetchBusinessRoles();
177
174
  return {
178
175
  payload: response,
179
176
  version: this.hashPayload(response),
180
177
  };
181
178
  }
182
179
  case "members": {
183
- const response = await services_1.businessService.fetchBusinessMembers(businessId);
180
+ const response = await businessService.fetchBusinessMembers(businessId);
184
181
  return {
185
182
  payload: response,
186
183
  version: this.hashPayload(response),
187
184
  };
188
185
  }
189
186
  case "tax-rules": {
190
- const response = await services_1.businessService.fetchBusinessTaxRules(businessId);
187
+ const response = await businessService.fetchBusinessTaxRules(businessId);
191
188
  return {
192
189
  payload: response,
193
190
  version: this.hashPayload(response),
194
191
  };
195
192
  }
196
193
  case "business:profile": {
197
- const response = await services_1.businessService.fetchBusinessById(businessId);
194
+ const response = await businessService.fetchBusinessById(businessId);
198
195
  return {
199
196
  payload: response,
200
197
  version: this.hashPayload(response),
201
198
  };
202
199
  }
203
200
  case "operating-hours": {
204
- const response = await services_1.businessService.fetchOperatingHours(businessId);
201
+ const response = await businessService.fetchOperatingHours(businessId);
205
202
  return {
206
203
  payload: response,
207
204
  version: this.hashPayload(response),
@@ -221,12 +218,12 @@ class ReferenceSyncService {
221
218
  try {
222
219
  const urls = [];
223
220
  if (keys.includes("menu:items")) {
224
- const cached = await (0, operations_1.getReferenceData)(db, businessId, "menu:items");
221
+ const cached = await getReferenceData(db, businessId, "menu:items");
225
222
  const items = cached?.payload?.data ?? [];
226
223
  urls.push(...items.map((item) => item.image_url));
227
224
  }
228
225
  if (keys.includes("business:profile")) {
229
- const cached = await (0, operations_1.getReferenceData)(db, businessId, "business:profile");
226
+ const cached = await getReferenceData(db, businessId, "business:profile");
230
227
  const business = cached?.payload?.data;
231
228
  if (business) {
232
229
  urls.push(business.logo_url, business.cover_image_url);
@@ -234,18 +231,18 @@ class ReferenceSyncService {
234
231
  }
235
232
  if (urls.length === 0)
236
233
  return;
237
- const cachedImages = await (0, image_cache_1.cacheImageBatch)(urls, {
234
+ const cachedImages = await cacheImageBatch(urls, {
238
235
  skipIfCached: true,
239
236
  });
240
- sync_logger_1.syncLogger.debug("ReferenceSync", "Reference images cached", {
237
+ syncLogger.debug("ReferenceSync", "Reference images cached", {
241
238
  businessId,
242
239
  keys,
243
240
  count: cachedImages.length,
244
241
  });
245
- await (0, image_cache_1.pruneImageCache)(urls);
242
+ await pruneImageCache(urls);
246
243
  }
247
244
  catch (error) {
248
- sync_logger_1.syncLogger.warn("ReferenceSync", "Failed to cache reference images", {
245
+ syncLogger.warn("ReferenceSync", "Failed to cache reference images", {
249
246
  error: String(error),
250
247
  });
251
248
  }
@@ -263,8 +260,8 @@ class ReferenceSyncService {
263
260
  return `local-${Math.abs(hash).toString(16)}`;
264
261
  }
265
262
  async getCached(businessId, key) {
266
- const db = await (0, connection_1.openSyncDatabase)();
267
- return (0, operations_1.getReferenceData)(db, businessId, key);
263
+ const db = await openSyncDatabase();
264
+ return getReferenceData(db, businessId, key);
268
265
  }
269
266
  }
270
- exports.referenceSyncService = new ReferenceSyncService();
267
+ export const referenceSyncService = new ReferenceSyncService();
@@ -1,4 +1,3 @@
1
- "use strict";
2
1
  /**
3
2
  * Types for reference data synchronization.
4
3
  *
@@ -9,4 +8,4 @@
9
8
  * It is synchronized separately from transactional data through the
10
9
  * ReferenceSyncService.
11
10
  */
12
- Object.defineProperty(exports, "__esModule", { value: true });
11
+ export {};
@@ -1,4 +1,3 @@
1
- "use strict";
2
1
  /**
3
2
  * Order Repository.
4
3
  *
@@ -8,10 +7,8 @@
8
7
  * In Phase 1, commands execute immediately through the REST transport.
9
8
  * Future phases will queue commands when offline.
10
9
  */
11
- Object.defineProperty(exports, "__esModule", { value: true });
12
- exports.orderRepository = void 0;
13
- const engine_1 = require("../sync/engine");
14
- const command_builder_1 = require("../sync/command-builder");
10
+ import { syncEngine } from "../sync/engine";
11
+ import { buildCommand } from "../sync/command-builder";
15
12
  async function executeCommand(command) {
16
13
  console.debug("[OrderRepository] Dispatching command", JSON.stringify({
17
14
  command_id: command.command_id,
@@ -21,7 +18,7 @@ async function executeCommand(command) {
21
18
  payload_keys: Object.keys(command.payload ?? {}),
22
19
  timestamp: new Date().toISOString(),
23
20
  }));
24
- const events = await engine_1.syncEngine.execute(command);
21
+ const events = await syncEngine.execute(command);
25
22
  const event = events[0];
26
23
  console.debug("[OrderRepository] Command result", JSON.stringify({
27
24
  command_id: command.command_id,
@@ -37,9 +34,9 @@ async function executeCommand(command) {
37
34
  }
38
35
  return event.payload;
39
36
  }
40
- exports.orderRepository = {
37
+ export const orderRepository = {
41
38
  async createOrder(input) {
42
- const command = (0, command_builder_1.buildCommand)({
39
+ const command = buildCommand({
43
40
  commandType: "order:create",
44
41
  businessId: input.businessId,
45
42
  entityId: input.entityId,
@@ -48,7 +45,7 @@ exports.orderRepository = {
48
45
  return executeCommand(command);
49
46
  },
50
47
  async acceptOrder(input) {
51
- const command = (0, command_builder_1.buildCommand)({
48
+ const command = buildCommand({
52
49
  commandType: "order:accept",
53
50
  businessId: input.businessId,
54
51
  entityId: input.orderId,
@@ -57,7 +54,7 @@ exports.orderRepository = {
57
54
  return executeCommand(command);
58
55
  },
59
56
  async rejectOrder(input) {
60
- const command = (0, command_builder_1.buildCommand)({
57
+ const command = buildCommand({
61
58
  commandType: "order:reject",
62
59
  businessId: input.businessId,
63
60
  entityId: input.orderId,
@@ -66,7 +63,7 @@ exports.orderRepository = {
66
63
  return executeCommand(command);
67
64
  },
68
65
  async startPreparingOrder(input) {
69
- const command = (0, command_builder_1.buildCommand)({
66
+ const command = buildCommand({
70
67
  commandType: "order:start_preparing",
71
68
  businessId: input.businessId,
72
69
  entityId: input.orderId,
@@ -75,7 +72,7 @@ exports.orderRepository = {
75
72
  return executeCommand(command);
76
73
  },
77
74
  async markOrderReady(input) {
78
- const command = (0, command_builder_1.buildCommand)({
75
+ const command = buildCommand({
79
76
  commandType: "order:mark_ready",
80
77
  businessId: input.businessId,
81
78
  entityId: input.orderId,
@@ -84,7 +81,7 @@ exports.orderRepository = {
84
81
  return executeCommand(command);
85
82
  },
86
83
  async completePickup(input) {
87
- const command = (0, command_builder_1.buildCommand)({
84
+ const command = buildCommand({
88
85
  commandType: "order:complete_pickup",
89
86
  businessId: input.businessId,
90
87
  entityId: input.orderId,
@@ -93,7 +90,7 @@ exports.orderRepository = {
93
90
  return executeCommand(command);
94
91
  },
95
92
  async cancelOrder(input) {
96
- const command = (0, command_builder_1.buildCommand)({
93
+ const command = buildCommand({
97
94
  commandType: "order:cancel",
98
95
  businessId: input.businessId,
99
96
  entityId: input.orderId,
@@ -102,13 +99,13 @@ exports.orderRepository = {
102
99
  return executeCommand(command);
103
100
  },
104
101
  async confirmHandover(input) {
105
- const command = (0, command_builder_1.buildCommand)({
102
+ const command = buildCommand({
106
103
  commandType: "delivery:confirm_handover",
107
104
  businessId: input.businessId,
108
105
  entityId: input.deliveryId,
109
106
  payload: {},
110
107
  });
111
- const events = await engine_1.syncEngine.execute(command);
108
+ const events = await syncEngine.execute(command);
112
109
  const event = events[0];
113
110
  if (!event) {
114
111
  throw new Error("OrderRepository: confirmHandover returned no events");
@@ -116,13 +113,13 @@ exports.orderRepository = {
116
113
  return event.payload;
117
114
  },
118
115
  async assignRider(input) {
119
- const command = (0, command_builder_1.buildCommand)({
116
+ const command = buildCommand({
120
117
  commandType: "delivery:assign",
121
118
  businessId: input.businessId,
122
119
  entityId: input.orderId,
123
120
  payload: { rider_id: input.riderId },
124
121
  });
125
- const events = await engine_1.syncEngine.execute(command);
122
+ const events = await syncEngine.execute(command);
126
123
  const event = events[0];
127
124
  if (!event) {
128
125
  throw new Error("OrderRepository: assignRider returned no events");
@@ -1,20 +1,17 @@
1
- "use strict";
2
1
  /**
3
2
  * POS Repository.
4
3
  *
5
4
  * Domain-specific operations for the POS terminal. Builds on OrderRepository
6
5
  * for commands and keeps read/query operations behind a repository interface.
7
6
  */
8
- Object.defineProperty(exports, "__esModule", { value: true });
9
- exports.posRepository = void 0;
10
- const services_1 = require("../adapters/services");
11
- const order_repository_1 = require("./order.repository");
12
- exports.posRepository = {
7
+ import { posService } from "../adapters/services";
8
+ import { orderRepository } from "./order.repository";
9
+ export const posRepository = {
13
10
  async createOrder(businessId, data, entityId) {
14
- return order_repository_1.orderRepository.createOrder({ businessId, data, entityId });
11
+ return orderRepository.createOrder({ businessId, data, entityId });
15
12
  },
16
13
  async fetchPreview(input) {
17
- const res = await services_1.posService.fetchPOSOrderPreview(input.businessId, {
14
+ const res = await posService.fetchPOSOrderPreview(input.businessId, {
18
15
  items: input.items,
19
16
  order_type: input.orderType,
20
17
  customer_name: input.customerName,
@@ -22,7 +19,7 @@ exports.posRepository = {
22
19
  return res;
23
20
  },
24
21
  async fetchOrders(businessId, params) {
25
- const res = await services_1.posService.fetchBusinessOrders(businessId, params);
22
+ const res = await posService.fetchBusinessOrders(businessId, params);
26
23
  return res;
27
24
  },
28
25
  };
@@ -1,23 +1,18 @@
1
- "use strict";
2
1
  /**
3
2
  * Command builder helpers.
4
3
  *
5
4
  * Centralizes creation of Command objects with consistent metadata
6
5
  * (command_id, user_id, device_id, timestamps).
7
6
  */
8
- Object.defineProperty(exports, "__esModule", { value: true });
9
- exports.getAppInstanceId = void 0;
10
- exports.buildCommand = buildCommand;
11
- const auth_1 = require("../adapters/auth");
12
- const devices_1 = require("../adapters/devices");
13
- Object.defineProperty(exports, "getAppInstanceId", { enumerable: true, get: function () { return devices_1.getAppInstanceId; } });
14
- const uuid_1 = require("../utils/uuid");
15
- function buildCommand(options) {
16
- const user = auth_1.useAuthStore.getState().user;
7
+ import { useAuthStore } from "../adapters/auth";
8
+ import { getAppInstanceId } from "../adapters/devices";
9
+ import { generateCommandId } from "../utils/uuid";
10
+ export function buildCommand(options) {
11
+ const user = useAuthStore.getState().user;
17
12
  const userId = user?.id ?? "anonymous";
18
- const deviceId = (0, devices_1.getAppInstanceId)();
13
+ const deviceId = getAppInstanceId();
19
14
  return {
20
- command_id: (0, uuid_1.generateCommandId)(),
15
+ command_id: generateCommandId(),
21
16
  command_type: options.commandType,
22
17
  command_version: options.commandVersion ?? "1.0",
23
18
  business_id: options.businessId,
@@ -28,3 +23,4 @@ function buildCommand(options) {
28
23
  payload: options.payload,
29
24
  };
30
25
  }
26
+ export { getAppInstanceId };
@@ -1,4 +1,3 @@
1
- "use strict";
2
1
  /**
3
2
  * Command Queue Service.
4
3
  *
@@ -9,18 +8,16 @@
9
8
  * - Replay queued commands when a transport becomes available.
10
9
  * - Provide optimistic domain events so the UI can render pending orders.
11
10
  */
12
- Object.defineProperty(exports, "__esModule", { value: true });
13
- exports.commandQueueService = void 0;
14
- const connection_1 = require("../db/connection");
15
- const operations_1 = require("../db/operations");
16
- const sync_logger_1 = require("../utils/sync-logger");
17
- const uuid_1 = require("../utils/uuid");
18
- const order_number_1 = require("./order-number");
11
+ import { getSyncDatabase, openSyncDatabase } from "../db/connection";
12
+ import { insertCommand, getPendingCommands, markCommandInFlight, updateCommandStatus, deleteCommand, insertEvent, } from "../db/operations";
13
+ import { syncLogger } from "../utils/sync-logger";
14
+ import { generateEventId } from "../utils/uuid";
15
+ import { generateLocalOrderNumber, generateLocalCalloutNumber, } from "./order-number";
19
16
  const MAX_RETRIES = 5;
20
17
  function buildOptimisticEvent(command) {
21
18
  const payload = command.payload;
22
19
  return {
23
- event_id: (0, uuid_1.generateEventId)(),
20
+ event_id: generateEventId(),
24
21
  event_type: `${command.command_type.replace(":", ".")}_queued`,
25
22
  event_version: "1.0",
26
23
  entity_id: command.entity_id ?? command.command_id,
@@ -40,11 +37,11 @@ function buildOptimisticOrder(command, payload) {
40
37
  const items = payload.items ?? [];
41
38
  const totalMinor = payload.total_minor ?? 0;
42
39
  const now = new Date().toISOString();
43
- const orderNumber = payload.order_number ?? (0, order_number_1.generateLocalOrderNumber)();
40
+ const orderNumber = payload.order_number ?? generateLocalOrderNumber();
44
41
  return {
45
42
  id: command.entity_id ?? command.command_id,
46
43
  order_number: orderNumber,
47
- callout_number: (0, order_number_1.generateLocalCalloutNumber)(),
44
+ callout_number: generateLocalCalloutNumber(),
48
45
  order_type: payload.order_type ?? "takeout",
49
46
  is_pos: true,
50
47
  customer_name: payload.customer_name ?? null,
@@ -104,7 +101,7 @@ function injectLocalOrderNumber(command) {
104
101
  ...command,
105
102
  payload: {
106
103
  ...payload,
107
- order_number: (0, order_number_1.generateLocalOrderNumber)(),
104
+ order_number: generateLocalOrderNumber(),
108
105
  },
109
106
  };
110
107
  }
@@ -121,19 +118,19 @@ class CommandQueueService {
121
118
  * Returns an optimistic domain event so the caller can update the UI.
122
119
  */
123
120
  async enqueue(command) {
124
- const db = (0, connection_1.getSyncDatabase)();
121
+ const db = getSyncDatabase();
125
122
  const preparedCommand = injectLocalOrderNumber(command);
126
- await (0, operations_1.insertCommand)(db, { command: preparedCommand, status: "pending" });
127
- sync_logger_1.syncLogger.command(preparedCommand, "queued");
128
- const pending = await (0, operations_1.getPendingCommands)(db, Number.MAX_SAFE_INTEGER);
129
- sync_logger_1.syncLogger.info("CommandQueueService", "Command queued offline", {
123
+ await insertCommand(db, { command: preparedCommand, status: "pending" });
124
+ syncLogger.command(preparedCommand, "queued");
125
+ const pending = await getPendingCommands(db, Number.MAX_SAFE_INTEGER);
126
+ syncLogger.info("CommandQueueService", "Command queued offline", {
130
127
  command_id: preparedCommand.command_id,
131
128
  command_type: preparedCommand.command_type,
132
129
  order_number: preparedCommand.payload.order_number ?? null,
133
130
  outbox_size: pending.length,
134
131
  });
135
132
  const event = buildOptimisticEvent(preparedCommand);
136
- sync_logger_1.syncLogger.info("CommandQueueService", "Optimistic event built", {
133
+ syncLogger.info("CommandQueueService", "Optimistic event built", {
137
134
  event_type: event.event_type,
138
135
  entity_id: event.entity_id,
139
136
  order_number: event.payload.order_number ?? null,
@@ -143,10 +140,10 @@ class CommandQueueService {
143
140
  // rehydrated (and shown) while still offline.
144
141
  if (preparedCommand.command_type === "order:create") {
145
142
  try {
146
- await (0, operations_1.insertEvent)(db, { event, origin: "local" });
143
+ await insertEvent(db, { event, origin: "local" });
147
144
  }
148
145
  catch (error) {
149
- sync_logger_1.syncLogger.error("CommandQueueService", "Failed to persist optimistic event", {
146
+ syncLogger.error("CommandQueueService", "Failed to persist optimistic event", {
150
147
  error: String(error),
151
148
  });
152
149
  }
@@ -157,7 +154,7 @@ class CommandQueueService {
157
154
  * Try to execute a single pending command through the current transport.
158
155
  */
159
156
  async processCommand(command) {
160
- const db = (0, connection_1.getSyncDatabase)();
157
+ const db = getSyncDatabase();
161
158
  const parsedCommand = {
162
159
  command_id: command.command_id,
163
160
  command_type: command.command_type,
@@ -170,20 +167,20 @@ class CommandQueueService {
170
167
  payload: command.payload,
171
168
  };
172
169
  if (command.retry_count >= MAX_RETRIES) {
173
- await (0, operations_1.updateCommandStatus)(db, command.command_id, "failed", "Max retry count exceeded");
170
+ await updateCommandStatus(db, command.command_id, "failed", "Max retry count exceeded");
174
171
  return;
175
172
  }
176
173
  if (!this.syncEngine) {
177
174
  throw new Error("CommandQueueService: SyncEngine not initialized");
178
175
  }
179
- await (0, operations_1.markCommandInFlight)(db, command.command_id);
176
+ await markCommandInFlight(db, command.command_id);
180
177
  try {
181
178
  const events = await this.syncEngine.execute(parsedCommand);
182
- await (0, operations_1.updateCommandStatus)(db, command.command_id, "completed");
183
- sync_logger_1.syncLogger.command(parsedCommand, "completed", {
179
+ await updateCommandStatus(db, command.command_id, "completed");
180
+ syncLogger.command(parsedCommand, "completed", {
184
181
  event_count: events.length,
185
182
  });
186
- sync_logger_1.syncLogger.info("CommandQueueService", "Queued command replayed", {
183
+ syncLogger.info("CommandQueueService", "Queued command replayed", {
187
184
  command_id: command.command_id,
188
185
  command_type: command.command_type,
189
186
  event_count: events.length,
@@ -191,8 +188,8 @@ class CommandQueueService {
191
188
  }
192
189
  catch (error) {
193
190
  const message = error instanceof Error ? error.message : String(error);
194
- await (0, operations_1.updateCommandStatus)(db, command.command_id, "failed", message);
195
- sync_logger_1.syncLogger.command(parsedCommand, "failed", { error: message });
191
+ await updateCommandStatus(db, command.command_id, "failed", message);
192
+ syncLogger.command(parsedCommand, "failed", { error: message });
196
193
  throw error;
197
194
  }
198
195
  }
@@ -202,7 +199,7 @@ class CommandQueueService {
202
199
  */
203
200
  async replay() {
204
201
  if (this.replaying) {
205
- sync_logger_1.syncLogger.debug("CommandQueueService", "Replay already in progress");
202
+ syncLogger.debug("CommandQueueService", "Replay already in progress");
206
203
  return;
207
204
  }
208
205
  this.replaying = true;
@@ -210,11 +207,11 @@ class CommandQueueService {
210
207
  // Await open (not getSyncDatabase) so a cold-start replay triggered by a
211
208
  // connectivity event that fires before the DB open completes does not
212
209
  // throw "Sync database not initialized".
213
- const db = await (0, connection_1.openSyncDatabase)();
214
- const pending = await (0, operations_1.getPendingCommands)(db);
210
+ const db = await openSyncDatabase();
211
+ const pending = await getPendingCommands(db);
215
212
  if (pending.length === 0)
216
213
  return;
217
- sync_logger_1.syncLogger.info("CommandQueueService", "Replaying commands", {
214
+ syncLogger.info("CommandQueueService", "Replaying commands", {
218
215
  count: pending.length,
219
216
  });
220
217
  for (const command of pending) {
@@ -235,9 +232,9 @@ class CommandQueueService {
235
232
  * Cancel a queued command that has not yet been transmitted.
236
233
  */
237
234
  async cancel(commandId) {
238
- const db = (0, connection_1.getSyncDatabase)();
239
- await (0, operations_1.deleteCommand)(db, commandId);
240
- sync_logger_1.syncLogger.debug("CommandQueueService", "Command cancelled", {
235
+ const db = getSyncDatabase();
236
+ await deleteCommand(db, commandId);
237
+ syncLogger.debug("CommandQueueService", "Command cancelled", {
241
238
  commandId,
242
239
  });
243
240
  }
@@ -245,9 +242,9 @@ class CommandQueueService {
245
242
  * Return the number of commands currently in the outbox.
246
243
  */
247
244
  async getPendingCount() {
248
- const db = (0, connection_1.getSyncDatabase)();
249
- const commands = await (0, operations_1.getPendingCommands)(db, Number.MAX_SAFE_INTEGER);
245
+ const db = getSyncDatabase();
246
+ const commands = await getPendingCommands(db, Number.MAX_SAFE_INTEGER);
250
247
  return commands.length;
251
248
  }
252
249
  }
253
- exports.commandQueueService = new CommandQueueService();
250
+ export const commandQueueService = new CommandQueueService();