@withone/cli 1.37.1 → 1.37.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.
- package/dist/index.js +107 -32
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -4853,30 +4853,82 @@ function handleId(response, config2, records) {
|
|
|
4853
4853
|
import fs9 from "fs";
|
|
4854
4854
|
import path9 from "path";
|
|
4855
4855
|
var SYNC_DIR = path9.join(".one", "sync");
|
|
4856
|
-
var
|
|
4857
|
-
|
|
4856
|
+
var STATE_DIR = path9.join(SYNC_DIR, "state");
|
|
4857
|
+
var LEGACY_STATE_FILE = path9.join(SYNC_DIR, "sync_state.json");
|
|
4858
|
+
function modelFilePath(platform, model) {
|
|
4859
|
+
return path9.join(STATE_DIR, platform, `${model}.json`);
|
|
4860
|
+
}
|
|
4861
|
+
function migrateLegacyIfNeeded() {
|
|
4862
|
+
if (!fs9.existsSync(LEGACY_STATE_FILE)) return;
|
|
4858
4863
|
try {
|
|
4859
|
-
|
|
4860
|
-
const
|
|
4861
|
-
|
|
4864
|
+
const raw = fs9.readFileSync(LEGACY_STATE_FILE, "utf-8");
|
|
4865
|
+
const legacy = JSON.parse(raw);
|
|
4866
|
+
for (const [platform, models] of Object.entries(legacy)) {
|
|
4867
|
+
for (const [model, modelState] of Object.entries(models)) {
|
|
4868
|
+
if (fs9.existsSync(modelFilePath(platform, model))) continue;
|
|
4869
|
+
writeModelFile(platform, model, modelState);
|
|
4870
|
+
}
|
|
4871
|
+
}
|
|
4872
|
+
fs9.unlinkSync(LEGACY_STATE_FILE);
|
|
4862
4873
|
} catch {
|
|
4863
|
-
|
|
4874
|
+
try {
|
|
4875
|
+
fs9.unlinkSync(LEGACY_STATE_FILE);
|
|
4876
|
+
} catch {
|
|
4877
|
+
}
|
|
4864
4878
|
}
|
|
4865
4879
|
}
|
|
4866
|
-
function
|
|
4867
|
-
|
|
4868
|
-
|
|
4880
|
+
function writeModelFile(platform, model, state) {
|
|
4881
|
+
const dir = path9.join(STATE_DIR, platform);
|
|
4882
|
+
fs9.mkdirSync(dir, { recursive: true });
|
|
4883
|
+
const file = path9.join(dir, `${model}.json`);
|
|
4884
|
+
const tmp = `${file}.${process.pid}.${Math.random().toString(36).slice(2, 10)}.tmp`;
|
|
4869
4885
|
fs9.writeFileSync(tmp, JSON.stringify(state, null, 2));
|
|
4870
|
-
fs9.renameSync(tmp,
|
|
4886
|
+
fs9.renameSync(tmp, file);
|
|
4887
|
+
}
|
|
4888
|
+
function readModelFile(platform, model) {
|
|
4889
|
+
try {
|
|
4890
|
+
const raw = fs9.readFileSync(modelFilePath(platform, model), "utf-8");
|
|
4891
|
+
return JSON.parse(raw);
|
|
4892
|
+
} catch {
|
|
4893
|
+
return null;
|
|
4894
|
+
}
|
|
4895
|
+
}
|
|
4896
|
+
function readSyncState() {
|
|
4897
|
+
migrateLegacyIfNeeded();
|
|
4898
|
+
const result = {};
|
|
4899
|
+
let platforms;
|
|
4900
|
+
try {
|
|
4901
|
+
platforms = fs9.readdirSync(STATE_DIR);
|
|
4902
|
+
} catch {
|
|
4903
|
+
return result;
|
|
4904
|
+
}
|
|
4905
|
+
for (const platform of platforms) {
|
|
4906
|
+
const platformDir = path9.join(STATE_DIR, platform);
|
|
4907
|
+
let entries;
|
|
4908
|
+
try {
|
|
4909
|
+
entries = fs9.readdirSync(platformDir);
|
|
4910
|
+
} catch {
|
|
4911
|
+
continue;
|
|
4912
|
+
}
|
|
4913
|
+
for (const entry of entries) {
|
|
4914
|
+
if (!entry.endsWith(".json")) continue;
|
|
4915
|
+
const model = entry.slice(0, -".json".length);
|
|
4916
|
+
const modelState = readModelFile(platform, model);
|
|
4917
|
+
if (modelState) {
|
|
4918
|
+
if (!result[platform]) result[platform] = {};
|
|
4919
|
+
result[platform][model] = modelState;
|
|
4920
|
+
}
|
|
4921
|
+
}
|
|
4922
|
+
}
|
|
4923
|
+
return result;
|
|
4871
4924
|
}
|
|
4872
4925
|
function getModelState(platform, model) {
|
|
4873
|
-
|
|
4874
|
-
return
|
|
4926
|
+
migrateLegacyIfNeeded();
|
|
4927
|
+
return readModelFile(platform, model);
|
|
4875
4928
|
}
|
|
4876
4929
|
function updateModelState(platform, model, partial) {
|
|
4877
|
-
|
|
4878
|
-
|
|
4879
|
-
const existing = state[platform][model] ?? {
|
|
4930
|
+
migrateLegacyIfNeeded();
|
|
4931
|
+
const existing = readModelFile(platform, model) ?? {
|
|
4880
4932
|
lastSync: null,
|
|
4881
4933
|
lastCursor: null,
|
|
4882
4934
|
totalRecords: 0,
|
|
@@ -4884,21 +4936,26 @@ function updateModelState(platform, model, partial) {
|
|
|
4884
4936
|
since: null,
|
|
4885
4937
|
status: "idle"
|
|
4886
4938
|
};
|
|
4887
|
-
|
|
4888
|
-
writeSyncState(state);
|
|
4939
|
+
writeModelFile(platform, model, { ...existing, ...partial });
|
|
4889
4940
|
}
|
|
4890
4941
|
function removeModelState(platform, model) {
|
|
4891
|
-
|
|
4892
|
-
|
|
4942
|
+
migrateLegacyIfNeeded();
|
|
4943
|
+
const platformDir = path9.join(STATE_DIR, platform);
|
|
4893
4944
|
if (model) {
|
|
4894
|
-
|
|
4895
|
-
|
|
4896
|
-
|
|
4945
|
+
try {
|
|
4946
|
+
fs9.unlinkSync(modelFilePath(platform, model));
|
|
4947
|
+
} catch {
|
|
4948
|
+
}
|
|
4949
|
+
try {
|
|
4950
|
+
if (fs9.readdirSync(platformDir).length === 0) fs9.rmdirSync(platformDir);
|
|
4951
|
+
} catch {
|
|
4897
4952
|
}
|
|
4898
4953
|
} else {
|
|
4899
|
-
|
|
4954
|
+
try {
|
|
4955
|
+
fs9.rmSync(platformDir, { recursive: true, force: true });
|
|
4956
|
+
} catch {
|
|
4957
|
+
}
|
|
4900
4958
|
}
|
|
4901
|
-
writeSyncState(state);
|
|
4902
4959
|
}
|
|
4903
4960
|
|
|
4904
4961
|
// src/lib/sync/db.ts
|
|
@@ -5721,10 +5778,10 @@ async function syncModel(api, profile, options) {
|
|
|
5721
5778
|
}
|
|
5722
5779
|
const lock = options.dryRun ? null : acquireSyncLock(platform, model);
|
|
5723
5780
|
const existingState = getModelState(platform, model);
|
|
5724
|
-
if (existingState?.status === "syncing" && !options.
|
|
5725
|
-
|
|
5726
|
-
|
|
5727
|
-
|
|
5781
|
+
if (existingState?.status === "syncing" && !options.dryRun && !isAgentMode()) {
|
|
5782
|
+
process.stderr.write(
|
|
5783
|
+
`Recovered from crashed previous sync of ${platform}/${model} (state was 'syncing', no live owner)
|
|
5784
|
+
`
|
|
5728
5785
|
);
|
|
5729
5786
|
}
|
|
5730
5787
|
if (!profile.dateFilter && !options.dryRun && !options.fullRefresh && !isAgentMode()) {
|
|
@@ -5733,13 +5790,28 @@ async function syncModel(api, profile, options) {
|
|
|
5733
5790
|
`
|
|
5734
5791
|
);
|
|
5735
5792
|
}
|
|
5736
|
-
if (!options.dryRun) {
|
|
5737
|
-
updateModelState(platform, model, { status: "syncing" });
|
|
5738
|
-
}
|
|
5739
5793
|
let db = null;
|
|
5740
5794
|
let totalRecords = 0;
|
|
5741
5795
|
let pagesProcessed = 0;
|
|
5742
5796
|
let lastCursor = null;
|
|
5797
|
+
const signalCleanup = (signal) => {
|
|
5798
|
+
try {
|
|
5799
|
+
updateModelState(platform, model, { status: "failed", pagesProcessed, lastCursor });
|
|
5800
|
+
} catch {
|
|
5801
|
+
}
|
|
5802
|
+
try {
|
|
5803
|
+
if (lock) lock.release();
|
|
5804
|
+
} catch {
|
|
5805
|
+
}
|
|
5806
|
+
process.exit(signal === "SIGINT" ? 130 : 143);
|
|
5807
|
+
};
|
|
5808
|
+
const onSigint = () => signalCleanup("SIGINT");
|
|
5809
|
+
const onSigterm = () => signalCleanup("SIGTERM");
|
|
5810
|
+
if (!options.dryRun) {
|
|
5811
|
+
process.on("SIGINT", onSigint);
|
|
5812
|
+
process.on("SIGTERM", onSigterm);
|
|
5813
|
+
updateModelState(platform, model, { status: "syncing" });
|
|
5814
|
+
}
|
|
5743
5815
|
const seenIds = /* @__PURE__ */ new Set();
|
|
5744
5816
|
let hooksInserted = 0;
|
|
5745
5817
|
let hooksUpdated = 0;
|
|
@@ -6102,6 +6174,9 @@ async function syncModel(api, profile, options) {
|
|
|
6102
6174
|
wrapped._recordsSynced = totalRecords;
|
|
6103
6175
|
wrapped._pagesProcessed = pagesProcessed;
|
|
6104
6176
|
throw wrapped;
|
|
6177
|
+
} finally {
|
|
6178
|
+
process.off("SIGINT", onSigint);
|
|
6179
|
+
process.off("SIGTERM", onSigterm);
|
|
6105
6180
|
}
|
|
6106
6181
|
}
|
|
6107
6182
|
|
|
@@ -8676,7 +8751,7 @@ Fetches ALL records and deletes local rows whose IDs are no longer in the source
|
|
|
8676
8751
|
.one/sync/
|
|
8677
8752
|
profiles/{platform}_{model}.json # sync profiles
|
|
8678
8753
|
data/{platform}.db # SQLite databases (WAL mode)
|
|
8679
|
-
|
|
8754
|
+
state/{platform}/{model}.json # per-model checkpoint tracking
|
|
8680
8755
|
events/{platform}_{model}.jsonl # change event logs (if onChange: "log")
|
|
8681
8756
|
logs/{platform}.log # cron run logs
|
|
8682
8757
|
locks/{platform}_{model}/ # cross-process sync locks
|