@fctc/interface-logic 4.2.7 → 4.2.8

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.
@@ -27,6 +27,7 @@ interface EnvConfig {
27
27
  localStorageUtils?: LocalStorageUtilsType;
28
28
  sessionStorageUtils?: any;
29
29
  envFile?: any;
30
+ isLocalMode?: boolean;
30
31
  }
31
32
  declare class EnvStore {
32
33
  private state;
@@ -27,6 +27,7 @@ interface EnvConfig {
27
27
  localStorageUtils?: LocalStorageUtilsType;
28
28
  sessionStorageUtils?: any;
29
29
  envFile?: any;
30
+ isLocalMode?: boolean;
30
31
  }
31
32
  declare class EnvStore {
32
33
  private state;
package/dist/hooks.d.mts CHANGED
@@ -2,6 +2,7 @@ import * as _tanstack_react_query from '@tanstack/react-query';
2
2
  import { L as LoginCredentialBody, d as SocialTokenBody, F as ForgotPasswordBody, u as updatePasswordBody, T as TThreadData, C as ContextApi, V as ViewData, c as GetSelectionType, f as GetViewParams } from './view-type-CfcWWR0w.mjs';
3
3
  import { B as BaseModelInit } from './base-model-type-DD8uZnDP.mjs';
4
4
  import { BaseModel } from './models.mjs';
5
+ import { P as ProgressCb } from './import-snapshot-Ds0gqFFm.mjs';
5
6
 
6
7
  declare const useForgotPassword: () => _tanstack_react_query.UseMutationResult<any, Error, string, unknown>;
7
8
 
@@ -733,4 +734,6 @@ declare const useUpdateOrderStatus: () => _tanstack_react_query.UseMutationResul
733
734
  xNode?: string;
734
735
  }, unknown>;
735
736
 
736
- export { useAddEntity, useButton, useChangeOrderPreparationState, useChangeStatus, useCheckPayment, useCreateEInvoice, useCreateEntity, useCreatePosConfig, useCreateSession, useDelete, useDeleteComment, useDeleteEntity, useDuplicateRecord, useExecuteImport, useExportExcel, useForgotPassword, useForgotPasswordSSO, useGenSerialNumber, useGeneratePaymentQrInfo, useGet2FAMethods, useGetASession, useGetAccessByCode, useGetActionDetail, useGetAll, useGetCalendar, useGetCity, useGetComment, useGetCompanyInfo, useGetConversionRate, useGetCountry, useGetCurrency, useGetCurrentCompany, useGetCurrentUser, useGetDataChart, useGetDetail, useGetExternalTabs, useGetFieldExport, useGetFieldOnChange, useGetFileExcel, useGetFormView, useGetGroups, useGetImage, useGetList, useGetListCompany, useGetListData, useGetListMyBankAccount, useGetMenu, useGetNotifications, useGetOrderLine, useGetPartnerTitle, useGetPinCode, useGetPos, useGetPreparationDisplayData, useGetPrintReport, useGetProGressBar, useGetProductImage, useGetProfile, useGetProvider, useGetResequence, useGetSelection, useGetTenantMapping, useGetThreadData, useGetThreadMessages, useGetToken, useGetUser, useGetVersion, useGetView, useGetWard, useGrantAccess, useHandleCloseSession, useHandleClosingDetailSession, useHandleClosingSession, useIsValidToken, useLoadAction, useLoadDataPosSession, useLoadMessage, useLoginCredential, useLoginSocial, useLogout, useManageOnChange, useManageSession, useModel, useOdooDataTransform, useOnChangeForm, useParsePreview, usePrint, useProcessOrder, useReadGroup, useRemoveRow, useRemoveTotpSetup, useRequestSetupTotp, useResetPassword, useResetPasswordSSO, useRunAction, useSave, useSavePinCode, useSearchJournal, useSendComment, useSettingsWebRead2fa, useSignInSSO, useSwitchLocale, useUpdateClosedSession, useUpdateEntity, useUpdateOrderStatus, useUpdatePassword, useUploadFile, useUploadFileExcel, useUploadIdFile, useUploadImage, useValidateActionToken, useVerify2FA, useVerifyTotp };
737
+ declare const useInitSnapshot: () => _tanstack_react_query.UseMutationResult<void, Error, ProgressCb | undefined, unknown>;
738
+
739
+ export { useAddEntity, useButton, useChangeOrderPreparationState, useChangeStatus, useCheckPayment, useCreateEInvoice, useCreateEntity, useCreatePosConfig, useCreateSession, useDelete, useDeleteComment, useDeleteEntity, useDuplicateRecord, useExecuteImport, useExportExcel, useForgotPassword, useForgotPasswordSSO, useGenSerialNumber, useGeneratePaymentQrInfo, useGet2FAMethods, useGetASession, useGetAccessByCode, useGetActionDetail, useGetAll, useGetCalendar, useGetCity, useGetComment, useGetCompanyInfo, useGetConversionRate, useGetCountry, useGetCurrency, useGetCurrentCompany, useGetCurrentUser, useGetDataChart, useGetDetail, useGetExternalTabs, useGetFieldExport, useGetFieldOnChange, useGetFileExcel, useGetFormView, useGetGroups, useGetImage, useGetList, useGetListCompany, useGetListData, useGetListMyBankAccount, useGetMenu, useGetNotifications, useGetOrderLine, useGetPartnerTitle, useGetPinCode, useGetPos, useGetPreparationDisplayData, useGetPrintReport, useGetProGressBar, useGetProductImage, useGetProfile, useGetProvider, useGetResequence, useGetSelection, useGetTenantMapping, useGetThreadData, useGetThreadMessages, useGetToken, useGetUser, useGetVersion, useGetView, useGetWard, useGrantAccess, useHandleCloseSession, useHandleClosingDetailSession, useHandleClosingSession, useInitSnapshot, useIsValidToken, useLoadAction, useLoadDataPosSession, useLoadMessage, useLoginCredential, useLoginSocial, useLogout, useManageOnChange, useManageSession, useModel, useOdooDataTransform, useOnChangeForm, useParsePreview, usePrint, useProcessOrder, useReadGroup, useRemoveRow, useRemoveTotpSetup, useRequestSetupTotp, useResetPassword, useResetPasswordSSO, useRunAction, useSave, useSavePinCode, useSearchJournal, useSendComment, useSettingsWebRead2fa, useSignInSSO, useSwitchLocale, useUpdateClosedSession, useUpdateEntity, useUpdateOrderStatus, useUpdatePassword, useUploadFile, useUploadFileExcel, useUploadIdFile, useUploadImage, useValidateActionToken, useVerify2FA, useVerifyTotp };
package/dist/hooks.d.ts CHANGED
@@ -2,6 +2,7 @@ import * as _tanstack_react_query from '@tanstack/react-query';
2
2
  import { L as LoginCredentialBody, d as SocialTokenBody, F as ForgotPasswordBody, u as updatePasswordBody, T as TThreadData, C as ContextApi, V as ViewData, c as GetSelectionType, f as GetViewParams } from './view-type-CfcWWR0w.js';
3
3
  import { B as BaseModelInit } from './base-model-type-DD8uZnDP.js';
4
4
  import { BaseModel } from './models.js';
5
+ import { P as ProgressCb } from './import-snapshot-Ds0gqFFm.js';
5
6
 
6
7
  declare const useForgotPassword: () => _tanstack_react_query.UseMutationResult<any, Error, string, unknown>;
7
8
 
@@ -733,4 +734,6 @@ declare const useUpdateOrderStatus: () => _tanstack_react_query.UseMutationResul
733
734
  xNode?: string;
734
735
  }, unknown>;
735
736
 
736
- export { useAddEntity, useButton, useChangeOrderPreparationState, useChangeStatus, useCheckPayment, useCreateEInvoice, useCreateEntity, useCreatePosConfig, useCreateSession, useDelete, useDeleteComment, useDeleteEntity, useDuplicateRecord, useExecuteImport, useExportExcel, useForgotPassword, useForgotPasswordSSO, useGenSerialNumber, useGeneratePaymentQrInfo, useGet2FAMethods, useGetASession, useGetAccessByCode, useGetActionDetail, useGetAll, useGetCalendar, useGetCity, useGetComment, useGetCompanyInfo, useGetConversionRate, useGetCountry, useGetCurrency, useGetCurrentCompany, useGetCurrentUser, useGetDataChart, useGetDetail, useGetExternalTabs, useGetFieldExport, useGetFieldOnChange, useGetFileExcel, useGetFormView, useGetGroups, useGetImage, useGetList, useGetListCompany, useGetListData, useGetListMyBankAccount, useGetMenu, useGetNotifications, useGetOrderLine, useGetPartnerTitle, useGetPinCode, useGetPos, useGetPreparationDisplayData, useGetPrintReport, useGetProGressBar, useGetProductImage, useGetProfile, useGetProvider, useGetResequence, useGetSelection, useGetTenantMapping, useGetThreadData, useGetThreadMessages, useGetToken, useGetUser, useGetVersion, useGetView, useGetWard, useGrantAccess, useHandleCloseSession, useHandleClosingDetailSession, useHandleClosingSession, useIsValidToken, useLoadAction, useLoadDataPosSession, useLoadMessage, useLoginCredential, useLoginSocial, useLogout, useManageOnChange, useManageSession, useModel, useOdooDataTransform, useOnChangeForm, useParsePreview, usePrint, useProcessOrder, useReadGroup, useRemoveRow, useRemoveTotpSetup, useRequestSetupTotp, useResetPassword, useResetPasswordSSO, useRunAction, useSave, useSavePinCode, useSearchJournal, useSendComment, useSettingsWebRead2fa, useSignInSSO, useSwitchLocale, useUpdateClosedSession, useUpdateEntity, useUpdateOrderStatus, useUpdatePassword, useUploadFile, useUploadFileExcel, useUploadIdFile, useUploadImage, useValidateActionToken, useVerify2FA, useVerifyTotp };
737
+ declare const useInitSnapshot: () => _tanstack_react_query.UseMutationResult<void, Error, ProgressCb | undefined, unknown>;
738
+
739
+ export { useAddEntity, useButton, useChangeOrderPreparationState, useChangeStatus, useCheckPayment, useCreateEInvoice, useCreateEntity, useCreatePosConfig, useCreateSession, useDelete, useDeleteComment, useDeleteEntity, useDuplicateRecord, useExecuteImport, useExportExcel, useForgotPassword, useForgotPasswordSSO, useGenSerialNumber, useGeneratePaymentQrInfo, useGet2FAMethods, useGetASession, useGetAccessByCode, useGetActionDetail, useGetAll, useGetCalendar, useGetCity, useGetComment, useGetCompanyInfo, useGetConversionRate, useGetCountry, useGetCurrency, useGetCurrentCompany, useGetCurrentUser, useGetDataChart, useGetDetail, useGetExternalTabs, useGetFieldExport, useGetFieldOnChange, useGetFileExcel, useGetFormView, useGetGroups, useGetImage, useGetList, useGetListCompany, useGetListData, useGetListMyBankAccount, useGetMenu, useGetNotifications, useGetOrderLine, useGetPartnerTitle, useGetPinCode, useGetPos, useGetPreparationDisplayData, useGetPrintReport, useGetProGressBar, useGetProductImage, useGetProfile, useGetProvider, useGetResequence, useGetSelection, useGetTenantMapping, useGetThreadData, useGetThreadMessages, useGetToken, useGetUser, useGetVersion, useGetView, useGetWard, useGrantAccess, useHandleCloseSession, useHandleClosingDetailSession, useHandleClosingSession, useInitSnapshot, useIsValidToken, useLoadAction, useLoadDataPosSession, useLoadMessage, useLoginCredential, useLoginSocial, useLogout, useManageOnChange, useManageSession, useModel, useOdooDataTransform, useOnChangeForm, useParsePreview, usePrint, useProcessOrder, useReadGroup, useRemoveRow, useRemoveTotpSetup, useRequestSetupTotp, useResetPassword, useResetPasswordSSO, useRunAction, useSave, useSavePinCode, useSearchJournal, useSendComment, useSettingsWebRead2fa, useSignInSSO, useSwitchLocale, useUpdateClosedSession, useUpdateEntity, useUpdateOrderStatus, useUpdatePassword, useUploadFile, useUploadFileExcel, useUploadIdFile, useUploadImage, useValidateActionToken, useVerify2FA, useVerifyTotp };
package/dist/hooks.js CHANGED
@@ -102,6 +102,7 @@ __export(hooks_exports, {
102
102
  useHandleCloseSession: () => use_handle_close_session_default,
103
103
  useHandleClosingDetailSession: () => use_handle_closing_detail_session_default,
104
104
  useHandleClosingSession: () => use_handle_closing_session_default,
105
+ useInitSnapshot: () => use_init_snapshot_default,
105
106
  useIsValidToken: () => use_isvalid_token_default,
106
107
  useLoadAction: () => use_load_action_default,
107
108
  useLoadDataPosSession: () => use_load_data_pos_session_default,
@@ -1763,9 +1764,9 @@ function applyBinaryOp(ast, context) {
1763
1764
  var DICT = {
1764
1765
  get(...args) {
1765
1766
  const { key, defValue } = parseArgs(args, ["key", "defValue"]);
1766
- const self = this;
1767
- if (key in self) {
1768
- return self[key];
1767
+ const self2 = this;
1768
+ if (key in self2) {
1769
+ return self2[key];
1769
1770
  } else if (defValue !== void 0) {
1770
1771
  return defValue;
1771
1772
  }
@@ -2401,7 +2402,8 @@ var initialState2 = {
2401
2402
  allowed_company_ids: [],
2402
2403
  lang: "vi_VN",
2403
2404
  tz: "Asia/Saigon"
2404
- }
2405
+ },
2406
+ isLocalMode: false
2405
2407
  };
2406
2408
  var envSlice = (0, import_toolkit2.createSlice)({
2407
2409
  name: "env",
@@ -5943,7 +5945,221 @@ var handleClosingSessionService = (env) => {
5943
5945
 
5944
5946
  // src/services/pos-service/load-data-pos-session.ts
5945
5947
  var import_react37 = require("react");
5948
+
5949
+ // src/services/filesystem-service/file-service.ts
5950
+ var import_filesystem = require("@capacitor/filesystem");
5951
+ var fileService = {
5952
+ async read(path) {
5953
+ try {
5954
+ const res = await import_filesystem.Filesystem.readFile({
5955
+ path,
5956
+ directory: import_filesystem.Directory.Data,
5957
+ encoding: import_filesystem.Encoding.UTF8
5958
+ });
5959
+ if (typeof res.data === "string") return res.data;
5960
+ if (res.data instanceof Blob) return await res.data.text();
5961
+ return null;
5962
+ } catch {
5963
+ return null;
5964
+ }
5965
+ },
5966
+ async write(path, data) {
5967
+ await import_filesystem.Filesystem.writeFile({
5968
+ path,
5969
+ data,
5970
+ directory: import_filesystem.Directory.Data,
5971
+ encoding: import_filesystem.Encoding.UTF8,
5972
+ recursive: true
5973
+ });
5974
+ },
5975
+ async writeAtomic(path, data) {
5976
+ const tempPath = path + ".tmp";
5977
+ await import_filesystem.Filesystem.writeFile({
5978
+ path: tempPath,
5979
+ data,
5980
+ directory: import_filesystem.Directory.Data,
5981
+ encoding: import_filesystem.Encoding.UTF8,
5982
+ recursive: true
5983
+ });
5984
+ try {
5985
+ await import_filesystem.Filesystem.deleteFile({
5986
+ path,
5987
+ directory: import_filesystem.Directory.Data
5988
+ });
5989
+ } catch {
5990
+ }
5991
+ await import_filesystem.Filesystem.rename({
5992
+ from: tempPath,
5993
+ to: path,
5994
+ directory: import_filesystem.Directory.Data
5995
+ });
5996
+ },
5997
+ async delete(path) {
5998
+ try {
5999
+ await import_filesystem.Filesystem.deleteFile({
6000
+ path,
6001
+ directory: import_filesystem.Directory.Data
6002
+ });
6003
+ } catch {
6004
+ }
6005
+ },
6006
+ async exists(path) {
6007
+ try {
6008
+ await import_filesystem.Filesystem.stat({
6009
+ path,
6010
+ directory: import_filesystem.Directory.Data
6011
+ });
6012
+ return true;
6013
+ } catch {
6014
+ return false;
6015
+ }
6016
+ },
6017
+ async mkdir(path) {
6018
+ try {
6019
+ await import_filesystem.Filesystem.mkdir({
6020
+ path,
6021
+ directory: import_filesystem.Directory.Data,
6022
+ recursive: true
6023
+ });
6024
+ } catch (e) {
6025
+ if (!String(e?.message).includes("Exists")) {
6026
+ throw e;
6027
+ }
6028
+ }
6029
+ },
6030
+ async list(path) {
6031
+ return import_filesystem.Filesystem.readdir({
6032
+ path,
6033
+ directory: import_filesystem.Directory.Data
6034
+ });
6035
+ },
6036
+ async getUri(path) {
6037
+ return import_filesystem.Filesystem.getUri({
6038
+ path,
6039
+ directory: import_filesystem.Directory.Data
6040
+ });
6041
+ }
6042
+ };
6043
+
6044
+ // src/services/filesystem-service/json-worker.ts
6045
+ var import_meta = {};
6046
+ self.addEventListener("message", async (ev) => {
6047
+ const { id, cmd, payload } = ev.data;
6048
+ try {
6049
+ if (cmd === "parse") {
6050
+ const parsed = JSON.parse(payload);
6051
+ self.postMessage({ id, ok: true, result: parsed });
6052
+ } else if (cmd === "stringify") {
6053
+ const str = JSON.stringify(payload);
6054
+ self.postMessage({ id, ok: true, result: str });
6055
+ }
6056
+ } catch (err) {
6057
+ self.postMessage({ id, ok: false, error: err?.message || String(err) });
6058
+ }
6059
+ });
6060
+ function spawnParseWorker(raw) {
6061
+ return new Promise((resolve, reject) => {
6062
+ const worker = new Worker(new URL("./json-worker.ts", import_meta.url), {
6063
+ type: "module"
6064
+ });
6065
+ const id = Math.random().toString(36).slice(2);
6066
+ worker.onmessage = (ev) => {
6067
+ const { ok, result, error } = ev.data;
6068
+ if (ok) {
6069
+ resolve(result);
6070
+ } else {
6071
+ reject(new Error(error));
6072
+ }
6073
+ worker.terminate();
6074
+ };
6075
+ worker.postMessage({ id, cmd: "parse", payload: raw });
6076
+ });
6077
+ }
6078
+ function spawnStringifyWorker(obj) {
6079
+ return new Promise((resolve, reject) => {
6080
+ const worker = new Worker(new URL("./json-worker.ts", import_meta.url), {
6081
+ type: "module"
6082
+ });
6083
+ worker.onmessage = (ev) => {
6084
+ const { ok, result, error } = ev.data;
6085
+ if (ok) resolve(result);
6086
+ else reject(new Error(error));
6087
+ worker.terminate();
6088
+ };
6089
+ worker.postMessage({ cmd: "stringify", payload: obj });
6090
+ });
6091
+ }
6092
+
6093
+ // src/services/filesystem-service/memory-cache.ts
6094
+ var MemoryCache = class {
6095
+ map = /* @__PURE__ */ new Map();
6096
+ get(k) {
6097
+ const e = this.map.get(k);
6098
+ if (!e) return null;
6099
+ if (e.ttl && Date.now() - e.t > e.ttl) {
6100
+ this.map.delete(k);
6101
+ return null;
6102
+ }
6103
+ return e.value;
6104
+ }
6105
+ set(k, v, ttl = 5 * 60 * 1e3) {
6106
+ this.map.set(k, { value: v, t: Date.now(), ttl });
6107
+ }
6108
+ del(k) {
6109
+ this.map.delete(k);
6110
+ }
6111
+ clear() {
6112
+ this.map.clear();
6113
+ }
6114
+ };
6115
+ var memoryCache = new MemoryCache();
6116
+
6117
+ // src/services/filesystem-service/model-loader.ts
6118
+ var MODELS_DIR = "pos/models";
6119
+ var MODELS_META_DIR = "pos/models_meta";
6120
+ async function loadData(includeMeta = true) {
6121
+ const listResult = await fileService.list(MODELS_DIR);
6122
+ if (!listResult || !Array.isArray(listResult.files)) {
6123
+ return {};
6124
+ }
6125
+ const result = {};
6126
+ for (const file of listResult.files) {
6127
+ if (file.type !== "file") continue;
6128
+ if (!file.name.endsWith(".json")) continue;
6129
+ const fileName = file.name;
6130
+ const modelName = fileName.replace(/\.json$/, "");
6131
+ const dataPath = `${MODELS_DIR}/${fileName}`;
6132
+ const metaPath = `${MODELS_META_DIR}/${encodeURIComponent(
6133
+ modelName
6134
+ )}.meta.json`;
6135
+ const rawData = await fileService.read(dataPath);
6136
+ if (!rawData) continue;
6137
+ const parsedData = await spawnParseWorker(rawData);
6138
+ const data = Array.isArray(parsedData) ? parsedData : [];
6139
+ if (!includeMeta) {
6140
+ result[modelName] = { data };
6141
+ continue;
6142
+ }
6143
+ const rawMeta = await fileService.read(metaPath);
6144
+ let fields = [];
6145
+ let relations = {};
6146
+ if (rawMeta) {
6147
+ const parsedMeta = await spawnParseWorker(rawMeta);
6148
+ fields = parsedMeta?.fields ?? [];
6149
+ relations = parsedMeta?.relations ?? {};
6150
+ }
6151
+ result[modelName] = {
6152
+ data,
6153
+ fields,
6154
+ relations
6155
+ };
6156
+ }
6157
+ return result;
6158
+ }
6159
+
6160
+ // src/services/pos-service/load-data-pos-session.ts
5946
6161
  var loadDataPosSessionService = (env) => {
6162
+ const isLocalMode = env?.isLocalMode;
5947
6163
  const loadDataPosSession = (0, import_react37.useCallback)(
5948
6164
  ({
5949
6165
  model,
@@ -5954,6 +6170,9 @@ var loadDataPosSessionService = (env) => {
5954
6170
  modelsToLoad = [],
5955
6171
  searchParams
5956
6172
  }) => {
6173
+ if (isLocalMode) {
6174
+ return loadData();
6175
+ }
5957
6176
  const jsonData = {
5958
6177
  model,
5959
6178
  method: "load_data" /* LOAD_DATA */,
@@ -5980,7 +6199,7 @@ var loadDataPosSessionService = (env) => {
5980
6199
  service
5981
6200
  );
5982
6201
  },
5983
- [env]
6202
+ [env, isLocalMode]
5984
6203
  );
5985
6204
  return {
5986
6205
  loadDataPosSession
@@ -6313,6 +6532,145 @@ var usePosService = () => {
6313
6532
  return service;
6314
6533
  };
6315
6534
 
6535
+ // src/services/filesystem-service/manifest.ts
6536
+ var MANIFEST_PATH = "pos/manifest.json";
6537
+ var MANIFEST_BAK_PATH = "pos/manifest.bak.json";
6538
+ async function writeManifest(manifest) {
6539
+ const oldRaw = await fileService.read(MANIFEST_PATH);
6540
+ if (oldRaw !== null) {
6541
+ await fileService.writeAtomic(MANIFEST_BAK_PATH, oldRaw);
6542
+ }
6543
+ await fileService.writeAtomic(MANIFEST_PATH, JSON.stringify(manifest));
6544
+ try {
6545
+ await fileService.delete(MANIFEST_BAK_PATH);
6546
+ } catch {
6547
+ }
6548
+ }
6549
+
6550
+ // src/services/filesystem-service/import-snapshot.ts
6551
+ var DATA_DIR = "pos";
6552
+ var MODELS_DIR2 = `${DATA_DIR}/models`;
6553
+ var MODELS_META_DIR2 = `${DATA_DIR}/models_meta`;
6554
+ var importSnapshot = async ({ data, onProgress }) => {
6555
+ onProgress?.(1, "Parsing snapshot");
6556
+ const parsed = await spawnParseWorker(data);
6557
+ const modelNames = Object.keys(parsed);
6558
+ const total = modelNames.length;
6559
+ const manifest = { version: (/* @__PURE__ */ new Date()).toISOString(), models: {} };
6560
+ const TMP_PREFIX = `pos/data/tmp_import_${Date.now()}`;
6561
+ await fileService.writeAtomic(`${TMP_PREFIX}/.marker`, "1");
6562
+ let i = 0;
6563
+ for (const model of modelNames) {
6564
+ i++;
6565
+ onProgress?.(
6566
+ Math.round(i / total * 100),
6567
+ `Processing ${model} (${i}/${total})`
6568
+ );
6569
+ const block = parsed[model];
6570
+ const dataPart = block?.data ?? block ?? [];
6571
+ const fields = block?.fields ?? [];
6572
+ const relations = block?.relations ?? {};
6573
+ const serialized = await spawnStringifyWorker(dataPart);
6574
+ const tmpModelPath = `${TMP_PREFIX}/${encodeURIComponent(model)}.json`;
6575
+ await fileService.writeAtomic(tmpModelPath, serialized);
6576
+ const meta = {
6577
+ fields,
6578
+ relations,
6579
+ count: Array.isArray(dataPart) ? dataPart.length : 0,
6580
+ writtenAt: (/* @__PURE__ */ new Date()).toISOString()
6581
+ };
6582
+ const tmpMetaPath = `${TMP_PREFIX}/${encodeURIComponent(model)}.meta.json`;
6583
+ await fileService.writeAtomic(tmpMetaPath, JSON.stringify(meta));
6584
+ manifest.models[model] = {
6585
+ file: `${MODELS_DIR2}/${encodeURIComponent(model)}.json`,
6586
+ metaFile: `${MODELS_META_DIR2}/${encodeURIComponent(model)}.meta.json`,
6587
+ count: meta.count,
6588
+ updatedAt: meta.writtenAt
6589
+ };
6590
+ }
6591
+ onProgress?.(95, "Committing import (moving files)");
6592
+ for (const model of modelNames) {
6593
+ const tmpModelPath = `${TMP_PREFIX}/${encodeURIComponent(model)}.json`;
6594
+ const finalModelPath = `${MODELS_DIR2}/${encodeURIComponent(model)}.json`;
6595
+ const tmpMetaPath = `${TMP_PREFIX}/${encodeURIComponent(model)}.meta.json`;
6596
+ const finalMetaPath = `${MODELS_META_DIR2}/${encodeURIComponent(
6597
+ model
6598
+ )}.meta.json`;
6599
+ const tmpRaw = await fileService.read(tmpModelPath);
6600
+ if (tmpRaw !== null) await fileService.writeAtomic(finalModelPath, tmpRaw);
6601
+ const tmpMetaRaw = await fileService.read(tmpMetaPath);
6602
+ if (tmpMetaRaw !== null)
6603
+ await fileService.writeAtomic(finalMetaPath, tmpMetaRaw);
6604
+ onProgress?.(
6605
+ 95 + Math.round(
6606
+ (Object.keys(manifest.models).indexOf(model) + 1) / modelNames.length * 5
6607
+ ),
6608
+ `Committed ${model}`
6609
+ );
6610
+ }
6611
+ await writeManifest(manifest);
6612
+ try {
6613
+ for (const model of modelNames) {
6614
+ await fileService.delete(
6615
+ `${TMP_PREFIX}/${encodeURIComponent(model)}.json`
6616
+ );
6617
+ await fileService.delete(
6618
+ `${TMP_PREFIX}/${encodeURIComponent(model)}.meta.json`
6619
+ );
6620
+ }
6621
+ await fileService.delete(`${TMP_PREFIX}/.marker`);
6622
+ } catch (e) {
6623
+ console.log("Failed to cleanup tmp import files:", e);
6624
+ }
6625
+ onProgress?.(100, "Import complete");
6626
+ return manifest;
6627
+ };
6628
+ var import_snapshot_default = importSnapshot;
6629
+
6630
+ // src/services/filesystem-service/init-snapshot.ts
6631
+ var isSnapshotReady = async () => {
6632
+ try {
6633
+ const raw = await fileService.read("pos/manifest.json");
6634
+ if (!raw) return false;
6635
+ const manifest = JSON.parse(raw);
6636
+ if (!manifest.models || typeof manifest.models !== "object") {
6637
+ return false;
6638
+ }
6639
+ const modelEntries = Object.values(manifest.models);
6640
+ if (modelEntries.length === 0) return false;
6641
+ const firstModel = modelEntries[0];
6642
+ if (!firstModel.file) return false;
6643
+ const modelExists = await fileService.exists(firstModel.file);
6644
+ return modelExists;
6645
+ } catch {
6646
+ return false;
6647
+ }
6648
+ };
6649
+ async function initSnapshot(onProgress) {
6650
+ const ready = await isSnapshotReady();
6651
+ if (ready) {
6652
+ console.log("skip initialization.");
6653
+ return;
6654
+ }
6655
+ console.log("initializing from data.json...");
6656
+ const jsonData = await fetch("/data.json").then((r) => r.text());
6657
+ if (!jsonData) {
6658
+ console.error("cannot load data.json");
6659
+ return;
6660
+ }
6661
+ await import_snapshot_default({
6662
+ data: jsonData,
6663
+ onProgress
6664
+ });
6665
+ }
6666
+
6667
+ // src/services/filesystem-service/index.ts
6668
+ var useFileSystemService = () => {
6669
+ return {
6670
+ initSnapshot
6671
+ };
6672
+ };
6673
+
6316
6674
  // src/hooks/auth/use-forgot-password.ts
6317
6675
  var useForgotPassword = () => {
6318
6676
  const { forgotPassword } = useAuthService();
@@ -8286,6 +8644,16 @@ var useUpdateOrderStatus = () => {
8286
8644
  });
8287
8645
  };
8288
8646
  var use_update_order_status_default = useUpdateOrderStatus;
8647
+
8648
+ // src/hooks/pos/use-init-snapshot.ts
8649
+ var import_react_query113 = require("@tanstack/react-query");
8650
+ var useInitSnapshot = () => {
8651
+ const fileSystem = useFileSystemService();
8652
+ return (0, import_react_query113.useMutation)({
8653
+ mutationFn: fileSystem.initSnapshot
8654
+ });
8655
+ };
8656
+ var use_init_snapshot_default = useInitSnapshot;
8289
8657
  // Annotate the CommonJS export names for ESM import in node:
8290
8658
  0 && (module.exports = {
8291
8659
  useAddEntity,
@@ -8360,6 +8728,7 @@ var use_update_order_status_default = useUpdateOrderStatus;
8360
8728
  useHandleCloseSession,
8361
8729
  useHandleClosingDetailSession,
8362
8730
  useHandleClosingSession,
8731
+ useInitSnapshot,
8363
8732
  useIsValidToken,
8364
8733
  useLoadAction,
8365
8734
  useLoadDataPosSession,