memorio 5.1.2 → 5.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.
- package/AGENTS.md +1 -3
- package/CHANGELOG.md +80 -0
- package/README.md +15 -2
- package/SUMMARY.md +2 -2
- package/examples/sqlite-batched-writes.ts +10 -7
- package/global.cjs +382 -210
- package/global.js +359 -186
- package/index.cjs +382 -210
- package/index.js +359 -186
- package/llms.txt +4 -2
- package/markdown/SQLITE.md +46 -20
- package/markdown/STORE.md +12 -12
- package/markdown/SYNC.md +18 -15
- package/modules/redux.cjs +0 -6
- package/modules/redux.cjs.map +1 -1
- package/modules/redux.js +0 -6
- package/modules/redux.js.map +1 -1
- package/package.json +7 -2
- package/types/sqlite.d.ts +58 -35
- package/vsix/memorio.vsix +0 -0
package/index.js
CHANGED
|
@@ -1092,6 +1092,123 @@ var init_store = __esm({
|
|
|
1092
1092
|
}
|
|
1093
1093
|
});
|
|
1094
1094
|
|
|
1095
|
+
// core/hlc.ts
|
|
1096
|
+
function getNodeId() {
|
|
1097
|
+
if (typeof globalThis === "undefined") return "node";
|
|
1098
|
+
try {
|
|
1099
|
+
if (typeof sessionStorage !== "undefined" && sessionStorage) {
|
|
1100
|
+
let id = sessionStorage.getItem(NODE_ID_KEY);
|
|
1101
|
+
if (!id) {
|
|
1102
|
+
id = generateNodeId();
|
|
1103
|
+
sessionStorage.setItem(NODE_ID_KEY, id);
|
|
1104
|
+
}
|
|
1105
|
+
return id;
|
|
1106
|
+
}
|
|
1107
|
+
} catch {
|
|
1108
|
+
}
|
|
1109
|
+
if (!globalThis.__memorioHlcNodeId) {
|
|
1110
|
+
globalThis.__memorioHlcNodeId = generateNodeId();
|
|
1111
|
+
}
|
|
1112
|
+
return globalThis.__memorioHlcNodeId;
|
|
1113
|
+
}
|
|
1114
|
+
function generateNodeId() {
|
|
1115
|
+
if (typeof crypto !== "undefined" && crypto.randomUUID) {
|
|
1116
|
+
return crypto.randomUUID().slice(0, 8);
|
|
1117
|
+
}
|
|
1118
|
+
return Math.random().toString(36).slice(2, 10);
|
|
1119
|
+
}
|
|
1120
|
+
function tick(_incoming) {
|
|
1121
|
+
const now2 = Date.now();
|
|
1122
|
+
const base = local.physical;
|
|
1123
|
+
let physical;
|
|
1124
|
+
let logical;
|
|
1125
|
+
if (now2 > base) {
|
|
1126
|
+
physical = now2;
|
|
1127
|
+
logical = 0;
|
|
1128
|
+
} else if (now2 < base) {
|
|
1129
|
+
physical = base;
|
|
1130
|
+
logical = local.logical + 1;
|
|
1131
|
+
} else {
|
|
1132
|
+
physical = base;
|
|
1133
|
+
logical = local.logical + 1;
|
|
1134
|
+
}
|
|
1135
|
+
local.physical = physical;
|
|
1136
|
+
local.logical = logical;
|
|
1137
|
+
return { physical, logical, node: local.node };
|
|
1138
|
+
}
|
|
1139
|
+
function receive(remote) {
|
|
1140
|
+
const now2 = Date.now();
|
|
1141
|
+
if (remote.physical > local.physical) {
|
|
1142
|
+
local.physical = remote.physical > now2 ? remote.physical : now2;
|
|
1143
|
+
local.logical = 1;
|
|
1144
|
+
} else if (remote.physical === local.physical) {
|
|
1145
|
+
local.logical = Math.max(local.logical, remote.logical) + 1;
|
|
1146
|
+
}
|
|
1147
|
+
local.node = getNodeId();
|
|
1148
|
+
return { ...local };
|
|
1149
|
+
}
|
|
1150
|
+
function compare(a, b) {
|
|
1151
|
+
if (a.physical !== b.physical) {
|
|
1152
|
+
return a.physical < b.physical ? -1 : 1;
|
|
1153
|
+
}
|
|
1154
|
+
if (a.logical !== b.logical) {
|
|
1155
|
+
return a.logical < b.logical ? -1 : 1;
|
|
1156
|
+
}
|
|
1157
|
+
if (a.node !== b.node) {
|
|
1158
|
+
return a.node < b.node ? -1 : 1;
|
|
1159
|
+
}
|
|
1160
|
+
return 0;
|
|
1161
|
+
}
|
|
1162
|
+
function happenedBefore(a, b) {
|
|
1163
|
+
return compare(a, b) < 0;
|
|
1164
|
+
}
|
|
1165
|
+
function serialize(hlc2) {
|
|
1166
|
+
return `hlc:${hlc2.physical}:${hlc2.logical}:${hlc2.node}`;
|
|
1167
|
+
}
|
|
1168
|
+
function parse(serialized) {
|
|
1169
|
+
if (!serialized.startsWith("hlc:")) return null;
|
|
1170
|
+
const parts = serialized.split(":");
|
|
1171
|
+
if (parts.length !== 4) return null;
|
|
1172
|
+
const physical = parseInt(parts[1], 10);
|
|
1173
|
+
const logical = parseInt(parts[2], 10);
|
|
1174
|
+
const node = parts[3];
|
|
1175
|
+
if (isNaN(physical) || isNaN(logical)) return null;
|
|
1176
|
+
return { physical, logical, node };
|
|
1177
|
+
}
|
|
1178
|
+
var NODE_ID_KEY, HLC_KEY, local, hlc;
|
|
1179
|
+
var init_hlc = __esm({
|
|
1180
|
+
"core/hlc.ts"() {
|
|
1181
|
+
init_esm_shims();
|
|
1182
|
+
NODE_ID_KEY = "__memorio_hlc_node";
|
|
1183
|
+
__name(getNodeId, "getNodeId");
|
|
1184
|
+
__name(generateNodeId, "generateNodeId");
|
|
1185
|
+
HLC_KEY = "__memorio_hlc_local";
|
|
1186
|
+
local = globalThis[HLC_KEY] || {
|
|
1187
|
+
physical: 0,
|
|
1188
|
+
logical: 0,
|
|
1189
|
+
node: getNodeId()
|
|
1190
|
+
};
|
|
1191
|
+
if (!globalThis[HLC_KEY]) {
|
|
1192
|
+
globalThis[HLC_KEY] = local;
|
|
1193
|
+
}
|
|
1194
|
+
__name(tick, "tick");
|
|
1195
|
+
__name(receive, "receive");
|
|
1196
|
+
__name(compare, "compare");
|
|
1197
|
+
__name(happenedBefore, "happenedBefore");
|
|
1198
|
+
__name(serialize, "serialize");
|
|
1199
|
+
__name(parse, "parse");
|
|
1200
|
+
hlc = {
|
|
1201
|
+
tick,
|
|
1202
|
+
receive,
|
|
1203
|
+
compare,
|
|
1204
|
+
happenedBefore,
|
|
1205
|
+
serialize,
|
|
1206
|
+
parse,
|
|
1207
|
+
getNodeId
|
|
1208
|
+
};
|
|
1209
|
+
}
|
|
1210
|
+
});
|
|
1211
|
+
|
|
1095
1212
|
// functions/idb/tools/db.create.ts
|
|
1096
1213
|
var db_create_exports = {};
|
|
1097
1214
|
var init_db_create = __esm({
|
|
@@ -1730,13 +1847,41 @@ var init_db_support2 = __esm({
|
|
|
1730
1847
|
});
|
|
1731
1848
|
|
|
1732
1849
|
// functions/sqlite/tools/persist.ts
|
|
1850
|
+
var persist_exports = {};
|
|
1851
|
+
__export(persist_exports, {
|
|
1852
|
+
CHECKPOINT_INTERVAL: () => CHECKPOINT_INTERVAL,
|
|
1853
|
+
DEBOUNCE_MS: () => DEBOUNCE_MS,
|
|
1854
|
+
_attachJournal: () => _attachJournal,
|
|
1855
|
+
_checkpoint: () => _checkpoint,
|
|
1856
|
+
_clearJournal: () => _clearJournal,
|
|
1857
|
+
_journalAppend: () => _journalAppend,
|
|
1858
|
+
_journalCount: () => _journalCount,
|
|
1859
|
+
_journalEntries: () => _journalEntries,
|
|
1860
|
+
_journalReplay: () => _journalReplay,
|
|
1861
|
+
_loadCheckpoint: () => _loadCheckpoint,
|
|
1862
|
+
_removeCheckpoint: () => _removeCheckpoint,
|
|
1863
|
+
_saveCheckpoint: () => _saveCheckpoint,
|
|
1864
|
+
_scheduleCheckpoint: () => _scheduleCheckpoint
|
|
1865
|
+
});
|
|
1733
1866
|
function _ns() {
|
|
1734
1867
|
const cfg = g.sqliteConfig || {};
|
|
1735
1868
|
return cfg.namespace ? `ns:${cfg.namespace}` : "default";
|
|
1736
1869
|
}
|
|
1737
|
-
function
|
|
1870
|
+
function _dbKey(name) {
|
|
1738
1871
|
return `memorio:sqlite:db:${_ns()}:${name}`;
|
|
1739
1872
|
}
|
|
1873
|
+
function _journalKey(name, seq) {
|
|
1874
|
+
return `memorio:sqlite:journal:${_ns()}:${name}:${seq}`;
|
|
1875
|
+
}
|
|
1876
|
+
function _journalIndexKey(name) {
|
|
1877
|
+
return `memorio:sqlite:journal:${_ns()}:${name}:index`;
|
|
1878
|
+
}
|
|
1879
|
+
function _journalSeqKey(name) {
|
|
1880
|
+
return `memorio:sqlite:journal:${_ns()}:${name}:seq`;
|
|
1881
|
+
}
|
|
1882
|
+
function _opCounterKey(name) {
|
|
1883
|
+
return `memorio:sqlite:journal:${_ns()}:${name}:ops`;
|
|
1884
|
+
}
|
|
1740
1885
|
function _b64encode2(buf) {
|
|
1741
1886
|
const bytes = buf instanceof Uint8Array ? buf : new Uint8Array(buf);
|
|
1742
1887
|
let binary = "";
|
|
@@ -1749,35 +1894,81 @@ function _b64decode2(b64) {
|
|
|
1749
1894
|
if (typeof Buffer !== "undefined") {
|
|
1750
1895
|
return new Uint8Array(Buffer.from(b64, "base64"));
|
|
1751
1896
|
}
|
|
1752
|
-
if (typeof atob
|
|
1753
|
-
|
|
1897
|
+
if (typeof atob === "function") {
|
|
1898
|
+
const binary = atob(b64);
|
|
1899
|
+
const len = binary.length;
|
|
1900
|
+
const out = new Uint8Array(len);
|
|
1901
|
+
for (let i = 0; i < len; i++) out[i] = binary.charCodeAt(i);
|
|
1902
|
+
return out;
|
|
1754
1903
|
}
|
|
1755
|
-
|
|
1756
|
-
const len = binary.length;
|
|
1757
|
-
const out = new Uint8Array(len);
|
|
1758
|
-
for (let i = 0; i < len; i++) out[i] = binary.charCodeAt(i);
|
|
1759
|
-
return out;
|
|
1904
|
+
throw new Error("memorio sqlite: no base64 decoder available");
|
|
1760
1905
|
}
|
|
1761
|
-
function
|
|
1762
|
-
|
|
1763
|
-
|
|
1764
|
-
|
|
1765
|
-
|
|
1766
|
-
|
|
1767
|
-
|
|
1768
|
-
|
|
1769
|
-
|
|
1770
|
-
|
|
1771
|
-
|
|
1772
|
-
|
|
1773
|
-
|
|
1774
|
-
|
|
1775
|
-
|
|
1776
|
-
|
|
1906
|
+
function _nextSeq(name) {
|
|
1907
|
+
const seq = (store.get(_journalSeqKey(name)) || 0) + 1;
|
|
1908
|
+
store.set(_journalSeqKey(name), seq);
|
|
1909
|
+
return seq;
|
|
1910
|
+
}
|
|
1911
|
+
function _journalAppend(name, sql, params) {
|
|
1912
|
+
const seq = _nextSeq(name);
|
|
1913
|
+
const entry = {
|
|
1914
|
+
hlc: hlc.serialize(hlc.tick()),
|
|
1915
|
+
sql,
|
|
1916
|
+
params: params || [],
|
|
1917
|
+
seq,
|
|
1918
|
+
ts: Date.now()
|
|
1919
|
+
};
|
|
1920
|
+
store.set(_journalKey(name, seq), entry);
|
|
1921
|
+
const idx = store.get(_journalIndexKey(name)) || [];
|
|
1922
|
+
idx.push(seq);
|
|
1923
|
+
store.set(_journalIndexKey(name), idx);
|
|
1924
|
+
return seq;
|
|
1925
|
+
}
|
|
1926
|
+
function _journalEntries(name) {
|
|
1927
|
+
const idx = store.get(_journalIndexKey(name)) || [];
|
|
1928
|
+
const entries = [];
|
|
1929
|
+
for (const seq of idx) {
|
|
1930
|
+
const raw = store.get(_journalKey(name, seq));
|
|
1931
|
+
if (raw && typeof raw === "object" && raw.hlc) entries.push(raw);
|
|
1932
|
+
}
|
|
1933
|
+
entries.sort((a, b) => {
|
|
1934
|
+
const ha = hlc.parse(a.hlc);
|
|
1935
|
+
const hb = hlc.parse(b.hlc);
|
|
1936
|
+
if (ha && hb) return hlc.compare(ha, hb);
|
|
1937
|
+
return a.seq - b.seq;
|
|
1777
1938
|
});
|
|
1939
|
+
return entries;
|
|
1940
|
+
}
|
|
1941
|
+
function _journalCount(name) {
|
|
1942
|
+
const idx = store.get(_journalIndexKey(name)) || [];
|
|
1943
|
+
return idx.length;
|
|
1944
|
+
}
|
|
1945
|
+
function _clearJournal(name) {
|
|
1946
|
+
const idx = store.get(_journalIndexKey(name)) || [];
|
|
1947
|
+
for (const seq of idx) {
|
|
1948
|
+
store.remove(_journalKey(name, seq));
|
|
1949
|
+
}
|
|
1950
|
+
store.remove(_journalIndexKey(name));
|
|
1951
|
+
store.remove(_journalSeqKey(name));
|
|
1952
|
+
store.remove(_opCounterKey(name));
|
|
1953
|
+
}
|
|
1954
|
+
async function _saveCheckpoint(name) {
|
|
1955
|
+
const db = g.__sqliteDbs && g.__sqliteDbs[name];
|
|
1956
|
+
if (!db || typeof db.export !== "function") return false;
|
|
1957
|
+
try {
|
|
1958
|
+
const blob = db.export();
|
|
1959
|
+
store.set(_dbKey(name), _b64encode2(blob));
|
|
1960
|
+
message_default(`Memorio SQLite: checkpoint saved for '${name}'`);
|
|
1961
|
+
return true;
|
|
1962
|
+
} catch (err) {
|
|
1963
|
+
if (db && db.version === "bun:sqlite") {
|
|
1964
|
+
return false;
|
|
1965
|
+
}
|
|
1966
|
+
console.warn("Memorio SQLite: checkpoint failed", err);
|
|
1967
|
+
return false;
|
|
1968
|
+
}
|
|
1778
1969
|
}
|
|
1779
|
-
function
|
|
1780
|
-
const b64 = store.get(
|
|
1970
|
+
function _loadCheckpoint(name) {
|
|
1971
|
+
const b64 = store.get(_dbKey(name));
|
|
1781
1972
|
if (!b64) return null;
|
|
1782
1973
|
try {
|
|
1783
1974
|
return _b64decode2(b64);
|
|
@@ -1785,48 +1976,108 @@ function loadSnapshot(name) {
|
|
|
1785
1976
|
return null;
|
|
1786
1977
|
}
|
|
1787
1978
|
}
|
|
1788
|
-
function
|
|
1789
|
-
store.remove(
|
|
1979
|
+
function _removeCheckpoint(name) {
|
|
1980
|
+
store.remove(_dbKey(name));
|
|
1790
1981
|
}
|
|
1791
|
-
function
|
|
1792
|
-
|
|
1793
|
-
|
|
1794
|
-
|
|
1795
|
-
|
|
1796
|
-
|
|
1797
|
-
|
|
1798
|
-
|
|
1799
|
-
|
|
1800
|
-
}
|
|
1801
|
-
}
|
|
1802
|
-
}
|
|
1803
|
-
|
|
1982
|
+
async function _journalReplay(name, db) {
|
|
1983
|
+
const entries = _journalEntries(name);
|
|
1984
|
+
if (!entries.length) return 0;
|
|
1985
|
+
let replayed = 0;
|
|
1986
|
+
for (const entry of entries) {
|
|
1987
|
+
try {
|
|
1988
|
+
db.run(entry.sql, entry.params || []);
|
|
1989
|
+
replayed++;
|
|
1990
|
+
} catch (err) {
|
|
1991
|
+
console.warn(`Memorio SQLite: failed to replay journal entry ${entry.seq} for '${name}'`, err);
|
|
1992
|
+
}
|
|
1993
|
+
}
|
|
1994
|
+
message_default(`Memorio SQLite: replayed ${replayed} journal entries for '${name}'`);
|
|
1995
|
+
return replayed;
|
|
1996
|
+
}
|
|
1997
|
+
function _scheduleCheckpoint(name) {
|
|
1998
|
+
if (_checkpointTimers[name]) clearTimeout(_checkpointTimers[name]);
|
|
1999
|
+
_checkpointTimers[name] = setTimeout(() => {
|
|
2000
|
+
_checkpointTimers[name] = null;
|
|
2001
|
+
void _checkpoint(name);
|
|
2002
|
+
}, DEBOUNCE_MS);
|
|
2003
|
+
}
|
|
2004
|
+
async function _checkpoint(name) {
|
|
2005
|
+
if (_checkpointTimers[name]) {
|
|
2006
|
+
clearTimeout(_checkpointTimers[name]);
|
|
2007
|
+
_checkpointTimers[name] = null;
|
|
2008
|
+
}
|
|
2009
|
+
const saved = await _saveCheckpoint(name);
|
|
2010
|
+
if (saved) _clearJournal(name);
|
|
2011
|
+
return saved;
|
|
2012
|
+
}
|
|
2013
|
+
function _attachJournal(name, db) {
|
|
2014
|
+
if (!db || typeof db.run !== "function") return;
|
|
2015
|
+
if (db.__memorioJournalAttached) return;
|
|
2016
|
+
db.__memorioJournalAttached = true;
|
|
2017
|
+
const originalRun = db.run.bind(db);
|
|
2018
|
+
db.run = function(sql, params) {
|
|
2019
|
+
const paramArr = Array.isArray(params) ? params : params !== void 0 ? [params] : [];
|
|
2020
|
+
_journalAppend(name, sql, paramArr);
|
|
2021
|
+
const ops = (store.get(_opCounterKey(name)) || 0) + 1;
|
|
2022
|
+
store.set(_opCounterKey(name), ops);
|
|
2023
|
+
if (ops >= CHECKPOINT_INTERVAL) {
|
|
2024
|
+
store.set(_opCounterKey(name), 0);
|
|
2025
|
+
void _checkpoint(name);
|
|
2026
|
+
} else {
|
|
2027
|
+
_scheduleCheckpoint(name);
|
|
2028
|
+
}
|
|
2029
|
+
return originalRun(sql, params);
|
|
2030
|
+
};
|
|
2031
|
+
if (typeof db.updateHook === "function") {
|
|
2032
|
+
try {
|
|
2033
|
+
db.updateHook(() => {
|
|
2034
|
+
_scheduleCheckpoint(name);
|
|
2035
|
+
});
|
|
2036
|
+
} catch (err) {
|
|
2037
|
+
console.warn("Memorio SQLite: could not attach updateHook", err);
|
|
2038
|
+
}
|
|
1804
2039
|
}
|
|
1805
2040
|
}
|
|
1806
|
-
var g,
|
|
2041
|
+
var g, CHECKPOINT_INTERVAL, DEBOUNCE_MS, _checkpointTimers;
|
|
1807
2042
|
var init_persist = __esm({
|
|
1808
2043
|
"functions/sqlite/tools/persist.ts"() {
|
|
1809
2044
|
init_esm_shims();
|
|
1810
2045
|
init_sqlite();
|
|
1811
2046
|
init_store();
|
|
2047
|
+
init_hlc();
|
|
1812
2048
|
init_message();
|
|
1813
2049
|
g = globalThis;
|
|
1814
|
-
|
|
1815
|
-
|
|
2050
|
+
CHECKPOINT_INTERVAL = 50;
|
|
2051
|
+
DEBOUNCE_MS = 250;
|
|
2052
|
+
_checkpointTimers = {};
|
|
1816
2053
|
__name(_ns, "_ns");
|
|
1817
|
-
__name(
|
|
2054
|
+
__name(_dbKey, "_dbKey");
|
|
2055
|
+
__name(_journalKey, "_journalKey");
|
|
2056
|
+
__name(_journalIndexKey, "_journalIndexKey");
|
|
2057
|
+
__name(_journalSeqKey, "_journalSeqKey");
|
|
2058
|
+
__name(_opCounterKey, "_opCounterKey");
|
|
1818
2059
|
__name(_b64encode2, "_b64encode");
|
|
1819
2060
|
__name(_b64decode2, "_b64decode");
|
|
1820
|
-
__name(
|
|
1821
|
-
__name(
|
|
1822
|
-
__name(
|
|
1823
|
-
__name(
|
|
2061
|
+
__name(_nextSeq, "_nextSeq");
|
|
2062
|
+
__name(_journalAppend, "_journalAppend");
|
|
2063
|
+
__name(_journalEntries, "_journalEntries");
|
|
2064
|
+
__name(_journalCount, "_journalCount");
|
|
2065
|
+
__name(_clearJournal, "_clearJournal");
|
|
2066
|
+
__name(_saveCheckpoint, "_saveCheckpoint");
|
|
2067
|
+
__name(_loadCheckpoint, "_loadCheckpoint");
|
|
2068
|
+
__name(_removeCheckpoint, "_removeCheckpoint");
|
|
2069
|
+
__name(_journalReplay, "_journalReplay");
|
|
2070
|
+
__name(_scheduleCheckpoint, "_scheduleCheckpoint");
|
|
2071
|
+
__name(_checkpoint, "_checkpoint");
|
|
2072
|
+
__name(_attachJournal, "_attachJournal");
|
|
1824
2073
|
sqlite.db.persist = async (name = "memorio") => {
|
|
1825
|
-
return
|
|
2074
|
+
return _checkpoint(name);
|
|
2075
|
+
};
|
|
2076
|
+
sqlite.db.flush = async (name = "memorio") => {
|
|
2077
|
+
return _checkpoint(name);
|
|
1826
2078
|
};
|
|
1827
2079
|
sqlite.db.download = async (name = "memorio", filename = `${name}.sqlite`) => {
|
|
1828
|
-
const
|
|
1829
|
-
const db = g3.__sqliteDbs && g3.__sqliteDbs[name];
|
|
2080
|
+
const db = g.__sqliteDbs && g.__sqliteDbs[name];
|
|
1830
2081
|
if (!db) {
|
|
1831
2082
|
console.warn(`Memorio SQLite: cannot download '${name}' - database not found. Create it with sqlite.db.create('${name}').`);
|
|
1832
2083
|
return false;
|
|
@@ -1839,18 +2090,18 @@ var init_persist = __esm({
|
|
|
1839
2090
|
return false;
|
|
1840
2091
|
}
|
|
1841
2092
|
if (!blob) return false;
|
|
1842
|
-
if (typeof
|
|
2093
|
+
if (typeof g.document === "undefined" || typeof g.Blob === "undefined") {
|
|
1843
2094
|
console.warn("Memorio SQLite: sqlite.db.download() requires a browser environment.");
|
|
1844
2095
|
return false;
|
|
1845
2096
|
}
|
|
1846
|
-
const URL =
|
|
2097
|
+
const URL = g.URL || g.webkitURL;
|
|
1847
2098
|
if (!URL || typeof URL.createObjectURL !== "function") return false;
|
|
1848
2099
|
const objectUrl = URL.createObjectURL(new Blob([blob], { type: "application/x-sqlite3" }));
|
|
1849
|
-
const a =
|
|
2100
|
+
const a = g.document.createElement("a");
|
|
1850
2101
|
a.style.display = "none";
|
|
1851
2102
|
a.href = objectUrl;
|
|
1852
2103
|
a.download = filename;
|
|
1853
|
-
|
|
2104
|
+
g.document.body.appendChild(a);
|
|
1854
2105
|
a.click();
|
|
1855
2106
|
setTimeout(() => {
|
|
1856
2107
|
try {
|
|
@@ -1865,7 +2116,7 @@ var init_persist = __esm({
|
|
|
1865
2116
|
const db = g.__sqliteDbs && g.__sqliteDbs[name];
|
|
1866
2117
|
if (db && typeof db.close === "function") {
|
|
1867
2118
|
try {
|
|
1868
|
-
await
|
|
2119
|
+
await _checkpoint(name);
|
|
1869
2120
|
} catch (_) {
|
|
1870
2121
|
}
|
|
1871
2122
|
try {
|
|
@@ -1879,15 +2130,22 @@ var init_persist = __esm({
|
|
|
1879
2130
|
const idx = g.sqlbases.findIndex((x) => x && x.name === name);
|
|
1880
2131
|
if (idx > -1) g.sqlbases.splice(idx, 1);
|
|
1881
2132
|
}
|
|
1882
|
-
|
|
1883
|
-
|
|
1884
|
-
|
|
1885
|
-
_exportTimers[name] = null;
|
|
2133
|
+
if (_checkpointTimers[name]) {
|
|
2134
|
+
clearTimeout(_checkpointTimers[name]);
|
|
2135
|
+
_checkpointTimers[name] = null;
|
|
1886
2136
|
}
|
|
1887
|
-
removeSnapshot(name);
|
|
1888
2137
|
};
|
|
1889
|
-
sqlite.db.loadSnapshot =
|
|
1890
|
-
sqlite.db.saveSnapshot =
|
|
2138
|
+
sqlite.db.loadSnapshot = _loadCheckpoint;
|
|
2139
|
+
sqlite.db.saveSnapshot = _saveCheckpoint;
|
|
2140
|
+
sqlite.db.removeSnapshot = _removeCheckpoint;
|
|
2141
|
+
sqlite.db.journal = {
|
|
2142
|
+
append: _journalAppend,
|
|
2143
|
+
entries: _journalEntries,
|
|
2144
|
+
count: _journalCount,
|
|
2145
|
+
clear: _clearJournal,
|
|
2146
|
+
replay: _journalReplay,
|
|
2147
|
+
checkpoint: _checkpoint
|
|
2148
|
+
};
|
|
1891
2149
|
}
|
|
1892
2150
|
});
|
|
1893
2151
|
|
|
@@ -1905,7 +2163,7 @@ var init_db_create2 = __esm({
|
|
|
1905
2163
|
const persistence = !!(opts && opts.persistence) || !!(g3.sqliteConfig && g3.sqliteConfig.persistence);
|
|
1906
2164
|
let data;
|
|
1907
2165
|
if (persistence && !opts.data) {
|
|
1908
|
-
const restored =
|
|
2166
|
+
const restored = _loadCheckpoint(name);
|
|
1909
2167
|
if (restored) data = restored;
|
|
1910
2168
|
}
|
|
1911
2169
|
const useData = opts && opts.data || data;
|
|
@@ -1927,7 +2185,13 @@ var init_db_create2 = __esm({
|
|
|
1927
2185
|
} else {
|
|
1928
2186
|
g3.sqlbases.push({ name, db, persistence: createOpts.persistence });
|
|
1929
2187
|
}
|
|
1930
|
-
if (persistence
|
|
2188
|
+
if (persistence && !opts.data) {
|
|
2189
|
+
_attachJournal(name, db);
|
|
2190
|
+
const replayed = await _journalReplay(name, db);
|
|
2191
|
+
if (replayed > 0) {
|
|
2192
|
+
message_default(`Memorio SQLite: replayed ${replayed} journal entries for '${name}'`);
|
|
2193
|
+
}
|
|
2194
|
+
}
|
|
1931
2195
|
return db;
|
|
1932
2196
|
};
|
|
1933
2197
|
}
|
|
@@ -1958,9 +2222,14 @@ var init_db_delete2 = __esm({
|
|
|
1958
2222
|
init_esm_shims();
|
|
1959
2223
|
init_sqlite();
|
|
1960
2224
|
init_message();
|
|
1961
|
-
|
|
2225
|
+
init_persist();
|
|
2226
|
+
sqlite.db.delete = async (name) => {
|
|
1962
2227
|
const dbs = globalThis.__sqliteDbs;
|
|
1963
2228
|
if (!dbs || !dbs[name]) return false;
|
|
2229
|
+
try {
|
|
2230
|
+
await _checkpoint(name);
|
|
2231
|
+
} catch (_) {
|
|
2232
|
+
}
|
|
1964
2233
|
try {
|
|
1965
2234
|
dbs[name].close();
|
|
1966
2235
|
} catch (_) {
|
|
@@ -1968,6 +2237,7 @@ var init_db_delete2 = __esm({
|
|
|
1968
2237
|
delete dbs[name];
|
|
1969
2238
|
const g3 = globalThis;
|
|
1970
2239
|
if (g3.sqlbases) g3.sqlbases = g3.sqlbases.filter((x) => x && x.name !== name);
|
|
2240
|
+
_removeCheckpoint(name);
|
|
1971
2241
|
message_default(`Memorio SQLite: database '${name}' deleted`);
|
|
1972
2242
|
return true;
|
|
1973
2243
|
};
|
|
@@ -2112,7 +2382,7 @@ var init_data_get2 = __esm({
|
|
|
2112
2382
|
});
|
|
2113
2383
|
|
|
2114
2384
|
// functions/sqlite/index.ts
|
|
2115
|
-
var _hasSqlJs, _hasBunSqlite, sqlite;
|
|
2385
|
+
var _hasSqlJs, _hasBunSqlite, sqlite, _toolsLoaded;
|
|
2116
2386
|
var init_sqlite = __esm({
|
|
2117
2387
|
"functions/sqlite/index.ts"() {
|
|
2118
2388
|
init_esm_shims();
|
|
@@ -2125,6 +2395,7 @@ var init_sqlite = __esm({
|
|
|
2125
2395
|
query: {},
|
|
2126
2396
|
data: {}
|
|
2127
2397
|
};
|
|
2398
|
+
_toolsLoaded = Promise.resolve();
|
|
2128
2399
|
sqlite.config = (opts) => {
|
|
2129
2400
|
const g3 = globalThis;
|
|
2130
2401
|
g3.sqliteConfig = { ...g3.sqliteConfig, ...opts };
|
|
@@ -2139,15 +2410,19 @@ var init_sqlite = __esm({
|
|
|
2139
2410
|
get: /* @__PURE__ */ __name(() => {
|
|
2140
2411
|
const g3 = globalThis;
|
|
2141
2412
|
if (!g3.sqliteReady) {
|
|
2142
|
-
g3.sqliteReady =
|
|
2413
|
+
g3.sqliteReady = _toolsLoaded.then(() => {
|
|
2414
|
+
if (typeof sqlite.db.getSQL !== "function") return;
|
|
2415
|
+
return sqlite.db.getSQL().then(() => {
|
|
2416
|
+
}).catch(() => {
|
|
2417
|
+
});
|
|
2143
2418
|
}).catch(() => {
|
|
2144
|
-
})
|
|
2419
|
+
});
|
|
2145
2420
|
}
|
|
2146
2421
|
return g3.sqliteReady;
|
|
2147
2422
|
}, "get")
|
|
2148
2423
|
});
|
|
2149
2424
|
if (_hasSqlJs || _hasBunSqlite) {
|
|
2150
|
-
(async () => {
|
|
2425
|
+
_toolsLoaded = (async () => {
|
|
2151
2426
|
Object.defineProperty(sqlite, "db", { value: {}, writable: false, configurable: true, enumerable: true });
|
|
2152
2427
|
Object.defineProperty(sqlite, "query", { value: {}, writable: false, configurable: true, enumerable: true });
|
|
2153
2428
|
Object.defineProperty(sqlite, "data", { value: {}, writable: false, configurable: true, enumerable: true });
|
|
@@ -2159,6 +2434,7 @@ var init_sqlite = __esm({
|
|
|
2159
2434
|
});
|
|
2160
2435
|
await Promise.all([
|
|
2161
2436
|
Promise.resolve().then(() => (init_db_support2(), db_support_exports2)),
|
|
2437
|
+
Promise.resolve().then(() => (init_persist(), persist_exports)),
|
|
2162
2438
|
Promise.resolve().then(() => (init_db_create2(), db_create_exports2)),
|
|
2163
2439
|
Promise.resolve().then(() => (init_db_get(), db_get_exports)),
|
|
2164
2440
|
Promise.resolve().then(() => (init_db_delete2(), db_delete_exports2)),
|
|
@@ -2379,121 +2655,11 @@ init_env();
|
|
|
2379
2655
|
// core/mutation/engine.ts
|
|
2380
2656
|
init_esm_shims();
|
|
2381
2657
|
init_internal();
|
|
2382
|
-
|
|
2383
|
-
// core/hlc.ts
|
|
2384
|
-
init_esm_shims();
|
|
2385
|
-
var NODE_ID_KEY = "__memorio_hlc_node";
|
|
2386
|
-
function getNodeId() {
|
|
2387
|
-
if (typeof globalThis === "undefined") return "node";
|
|
2388
|
-
try {
|
|
2389
|
-
if (typeof sessionStorage !== "undefined" && sessionStorage) {
|
|
2390
|
-
let id = sessionStorage.getItem(NODE_ID_KEY);
|
|
2391
|
-
if (!id) {
|
|
2392
|
-
id = generateNodeId();
|
|
2393
|
-
sessionStorage.setItem(NODE_ID_KEY, id);
|
|
2394
|
-
}
|
|
2395
|
-
return id;
|
|
2396
|
-
}
|
|
2397
|
-
} catch {
|
|
2398
|
-
}
|
|
2399
|
-
if (!globalThis.__memorioHlcNodeId) {
|
|
2400
|
-
globalThis.__memorioHlcNodeId = generateNodeId();
|
|
2401
|
-
}
|
|
2402
|
-
return globalThis.__memorioHlcNodeId;
|
|
2403
|
-
}
|
|
2404
|
-
__name(getNodeId, "getNodeId");
|
|
2405
|
-
function generateNodeId() {
|
|
2406
|
-
if (typeof crypto !== "undefined" && crypto.randomUUID) {
|
|
2407
|
-
return crypto.randomUUID().slice(0, 8);
|
|
2408
|
-
}
|
|
2409
|
-
return Math.random().toString(36).slice(2, 10);
|
|
2410
|
-
}
|
|
2411
|
-
__name(generateNodeId, "generateNodeId");
|
|
2412
|
-
var HLC_KEY = "__memorio_hlc_local";
|
|
2413
|
-
var local = globalThis[HLC_KEY] || {
|
|
2414
|
-
physical: 0,
|
|
2415
|
-
logical: 0,
|
|
2416
|
-
node: getNodeId()
|
|
2417
|
-
};
|
|
2418
|
-
if (!globalThis[HLC_KEY]) {
|
|
2419
|
-
globalThis[HLC_KEY] = local;
|
|
2420
|
-
}
|
|
2421
|
-
function tick(_incoming) {
|
|
2422
|
-
const now2 = Date.now();
|
|
2423
|
-
const base = local.physical;
|
|
2424
|
-
let physical;
|
|
2425
|
-
let logical;
|
|
2426
|
-
if (now2 > base) {
|
|
2427
|
-
physical = now2;
|
|
2428
|
-
logical = 0;
|
|
2429
|
-
} else if (now2 < base) {
|
|
2430
|
-
physical = base;
|
|
2431
|
-
logical = local.logical + 1;
|
|
2432
|
-
} else {
|
|
2433
|
-
physical = base;
|
|
2434
|
-
logical = local.logical + 1;
|
|
2435
|
-
}
|
|
2436
|
-
local.physical = physical;
|
|
2437
|
-
local.logical = logical;
|
|
2438
|
-
return { physical, logical, node: local.node };
|
|
2439
|
-
}
|
|
2440
|
-
__name(tick, "tick");
|
|
2441
|
-
function receive(remote) {
|
|
2442
|
-
const now2 = Date.now();
|
|
2443
|
-
if (remote.physical > local.physical) {
|
|
2444
|
-
local.physical = remote.physical > now2 ? remote.physical : now2;
|
|
2445
|
-
local.logical = 1;
|
|
2446
|
-
} else if (remote.physical === local.physical) {
|
|
2447
|
-
local.logical = Math.max(local.logical, remote.logical) + 1;
|
|
2448
|
-
}
|
|
2449
|
-
local.node = getNodeId();
|
|
2450
|
-
return { ...local };
|
|
2451
|
-
}
|
|
2452
|
-
__name(receive, "receive");
|
|
2453
|
-
function compare(a, b) {
|
|
2454
|
-
if (a.physical !== b.physical) {
|
|
2455
|
-
return a.physical < b.physical ? -1 : 1;
|
|
2456
|
-
}
|
|
2457
|
-
if (a.logical !== b.logical) {
|
|
2458
|
-
return a.logical < b.logical ? -1 : 1;
|
|
2459
|
-
}
|
|
2460
|
-
if (a.node !== b.node) {
|
|
2461
|
-
return a.node < b.node ? -1 : 1;
|
|
2462
|
-
}
|
|
2463
|
-
return 0;
|
|
2464
|
-
}
|
|
2465
|
-
__name(compare, "compare");
|
|
2466
|
-
function happenedBefore(a, b) {
|
|
2467
|
-
return compare(a, b) < 0;
|
|
2468
|
-
}
|
|
2469
|
-
__name(happenedBefore, "happenedBefore");
|
|
2470
|
-
function serialize(hlc2) {
|
|
2471
|
-
return `hlc:${hlc2.physical}:${hlc2.logical}:${hlc2.node}`;
|
|
2472
|
-
}
|
|
2473
|
-
__name(serialize, "serialize");
|
|
2474
|
-
function parse(serialized) {
|
|
2475
|
-
if (!serialized.startsWith("hlc:")) return null;
|
|
2476
|
-
const parts = serialized.split(":");
|
|
2477
|
-
if (parts.length !== 4) return null;
|
|
2478
|
-
const physical = parseInt(parts[1], 10);
|
|
2479
|
-
const logical = parseInt(parts[2], 10);
|
|
2480
|
-
const node = parts[3];
|
|
2481
|
-
if (isNaN(physical) || isNaN(logical)) return null;
|
|
2482
|
-
return { physical, logical, node };
|
|
2483
|
-
}
|
|
2484
|
-
__name(parse, "parse");
|
|
2485
|
-
var hlc = {
|
|
2486
|
-
tick,
|
|
2487
|
-
receive,
|
|
2488
|
-
compare,
|
|
2489
|
-
happenedBefore,
|
|
2490
|
-
serialize,
|
|
2491
|
-
parse,
|
|
2492
|
-
getNodeId
|
|
2493
|
-
};
|
|
2658
|
+
init_hlc();
|
|
2494
2659
|
|
|
2495
2660
|
// core/mutation/id.ts
|
|
2496
2661
|
init_esm_shims();
|
|
2662
|
+
init_hlc();
|
|
2497
2663
|
function generateMutationId() {
|
|
2498
2664
|
const now2 = hlc.tick();
|
|
2499
2665
|
return "m_" + encodeHLC(now2);
|
|
@@ -2585,6 +2751,7 @@ __name(mergePatches, "mergePatches");
|
|
|
2585
2751
|
// core/mutation/transaction.ts
|
|
2586
2752
|
init_esm_shims();
|
|
2587
2753
|
init_internal();
|
|
2754
|
+
init_hlc();
|
|
2588
2755
|
var TX_REGISTRY_KEY = "__memorio_transaction_registry__";
|
|
2589
2756
|
var registry = globalThis[TX_REGISTRY_KEY] || /* @__PURE__ */ new Map();
|
|
2590
2757
|
if (!globalThis[TX_REGISTRY_KEY]) {
|
|
@@ -4196,8 +4363,8 @@ function isAuditActive() {
|
|
|
4196
4363
|
return _auditLogger !== null;
|
|
4197
4364
|
}
|
|
4198
4365
|
__name(isAuditActive, "isAuditActive");
|
|
4199
|
-
function setAuditLogger(
|
|
4200
|
-
_auditLogger =
|
|
4366
|
+
function setAuditLogger(logger2) {
|
|
4367
|
+
_auditLogger = logger2;
|
|
4201
4368
|
}
|
|
4202
4369
|
__name(setAuditLogger, "setAuditLogger");
|
|
4203
4370
|
function logAudit(entry) {
|
|
@@ -4440,6 +4607,9 @@ var logger = {
|
|
|
4440
4607
|
exportLogs
|
|
4441
4608
|
};
|
|
4442
4609
|
|
|
4610
|
+
// index.ts
|
|
4611
|
+
init_hlc();
|
|
4612
|
+
|
|
4443
4613
|
// core/fractional.ts
|
|
4444
4614
|
init_esm_shims();
|
|
4445
4615
|
function generateBetween(left, right, minChars = 2) {
|
|
@@ -4632,7 +4802,7 @@ init_internal();
|
|
|
4632
4802
|
|
|
4633
4803
|
// package.json
|
|
4634
4804
|
var package_default = {
|
|
4635
|
-
version: "5.1.
|
|
4805
|
+
version: "5.1.3"};
|
|
4636
4806
|
|
|
4637
4807
|
// core/global.ts
|
|
4638
4808
|
init_env();
|
|
@@ -4653,10 +4823,12 @@ __name(typed, "typed");
|
|
|
4653
4823
|
init_esm_shims();
|
|
4654
4824
|
init_store();
|
|
4655
4825
|
init_idb();
|
|
4826
|
+
init_hlc();
|
|
4656
4827
|
init_env();
|
|
4657
4828
|
|
|
4658
4829
|
// functions/memory/journal.ts
|
|
4659
4830
|
init_esm_shims();
|
|
4831
|
+
init_hlc();
|
|
4660
4832
|
init_env();
|
|
4661
4833
|
init_store();
|
|
4662
4834
|
var g2 = globalThis;
|
|
@@ -5569,6 +5741,7 @@ if (!("memorio" in globalThis)) {
|
|
|
5569
5741
|
);
|
|
5570
5742
|
memorio.memory = memory;
|
|
5571
5743
|
memorio.encryption = encryption;
|
|
5744
|
+
memorio.sqlite = sqlite;
|
|
5572
5745
|
initializePlatform();
|
|
5573
5746
|
memorio.isBrowser = isBrowser;
|
|
5574
5747
|
memorio.isNode = isNode;
|