tinybase 4.0.0-beta.0 → 4.0.0-beta.1
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/lib/cjs/persister-browser.cjs +1 -0
- package/lib/cjs/persister-browser.cjs.gz +0 -0
- package/lib/cjs/persister-file.cjs +1 -0
- package/lib/cjs/persister-file.cjs.gz +0 -0
- package/lib/cjs/persister-remote.cjs +1 -0
- package/lib/cjs/persister-remote.cjs.gz +0 -0
- package/lib/cjs/persister-yjs.cjs +1 -1
- package/lib/cjs/persister-yjs.cjs.gz +0 -0
- package/lib/cjs/persisters.cjs +1 -1
- package/lib/cjs/persisters.cjs.gz +0 -0
- package/lib/cjs/store.cjs +1 -1
- package/lib/cjs/store.cjs.gz +0 -0
- package/lib/cjs/tinybase.cjs +1 -1
- package/lib/cjs/tinybase.cjs.gz +0 -0
- package/lib/cjs-es6/persister-browser.cjs +1 -0
- package/lib/cjs-es6/persister-browser.cjs.gz +0 -0
- package/lib/cjs-es6/persister-file.cjs +1 -0
- package/lib/cjs-es6/persister-file.cjs.gz +0 -0
- package/lib/cjs-es6/persister-remote.cjs +1 -0
- package/lib/cjs-es6/persister-remote.cjs.gz +0 -0
- package/lib/cjs-es6/persister-yjs.cjs +1 -1
- package/lib/cjs-es6/persister-yjs.cjs.gz +0 -0
- package/lib/cjs-es6/persisters.cjs +1 -1
- package/lib/cjs-es6/persisters.cjs.gz +0 -0
- package/lib/cjs-es6/store.cjs +1 -1
- package/lib/cjs-es6/store.cjs.gz +0 -0
- package/lib/cjs-es6/tinybase.cjs +1 -1
- package/lib/cjs-es6/tinybase.cjs.gz +0 -0
- package/lib/debug/persister-browser.js +148 -0
- package/lib/debug/persister-file.js +140 -0
- package/lib/debug/persister-remote.js +156 -0
- package/lib/debug/persister-yjs.js +30 -21
- package/lib/debug/persisters.js +24 -117
- package/lib/debug/store.js +36 -21
- package/lib/debug/tinybase.js +59 -135
- package/lib/es6/persister-browser.js +1 -0
- package/lib/es6/persister-browser.js.gz +0 -0
- package/lib/es6/persister-file.js +1 -0
- package/lib/es6/persister-file.js.gz +0 -0
- package/lib/es6/persister-remote.js +1 -0
- package/lib/es6/persister-remote.js.gz +0 -0
- package/lib/es6/persister-yjs.js +1 -1
- package/lib/es6/persister-yjs.js.gz +0 -0
- package/lib/es6/persisters.js +1 -1
- package/lib/es6/persisters.js.gz +0 -0
- package/lib/es6/store.js +1 -1
- package/lib/es6/store.js.gz +0 -0
- package/lib/es6/tinybase.js +1 -1
- package/lib/es6/tinybase.js.gz +0 -0
- package/lib/persister-browser.js +1 -0
- package/lib/persister-browser.js.gz +0 -0
- package/lib/persister-file.js +1 -0
- package/lib/persister-file.js.gz +0 -0
- package/lib/persister-remote.js +1 -0
- package/lib/persister-remote.js.gz +0 -0
- package/lib/persister-yjs.js +1 -1
- package/lib/persister-yjs.js.gz +0 -0
- package/lib/persisters.js +1 -1
- package/lib/persisters.js.gz +0 -0
- package/lib/store.js +1 -1
- package/lib/store.js.gz +0 -0
- package/lib/tinybase.js +1 -1
- package/lib/tinybase.js.gz +0 -0
- package/lib/types/persister-browser.d.ts +85 -0
- package/lib/types/persister-file.d.ts +41 -0
- package/lib/types/persister-remote.d.ts +60 -0
- package/lib/types/persisters.d.ts +40 -173
- package/lib/types/store.d.ts +117 -11
- package/lib/types/with-schemas/persister-browser.d.ts +103 -0
- package/lib/types/with-schemas/persister-file.d.ts +50 -0
- package/lib/types/with-schemas/persister-remote.d.ts +71 -0
- package/lib/types/with-schemas/persisters.d.ts +49 -214
- package/lib/types/with-schemas/store.d.ts +136 -11
- package/lib/umd/persister-browser.js +1 -0
- package/lib/umd/persister-browser.js.gz +0 -0
- package/lib/umd/persister-file.js +1 -0
- package/lib/umd/persister-file.js.gz +0 -0
- package/lib/umd/persister-remote.js +1 -0
- package/lib/umd/persister-remote.js.gz +0 -0
- package/lib/umd/persister-yjs.js +1 -1
- package/lib/umd/persister-yjs.js.gz +0 -0
- package/lib/umd/persisters.js +1 -1
- package/lib/umd/persisters.js.gz +0 -0
- package/lib/umd/store.js +1 -1
- package/lib/umd/store.js.gz +0 -0
- package/lib/umd/tinybase.js +1 -1
- package/lib/umd/tinybase.js.gz +0 -0
- package/lib/umd-es6/persister-browser.js +1 -0
- package/lib/umd-es6/persister-browser.js.gz +0 -0
- package/lib/umd-es6/persister-file.js +1 -0
- package/lib/umd-es6/persister-file.js.gz +0 -0
- package/lib/umd-es6/persister-remote.js +1 -0
- package/lib/umd-es6/persister-remote.js.gz +0 -0
- package/lib/umd-es6/persister-yjs.js +1 -1
- package/lib/umd-es6/persister-yjs.js.gz +0 -0
- package/lib/umd-es6/persisters.js +1 -1
- package/lib/umd-es6/persisters.js.gz +0 -0
- package/lib/umd-es6/store.js +1 -1
- package/lib/umd-es6/store.js.gz +0 -0
- package/lib/umd-es6/tinybase.js +1 -1
- package/lib/umd-es6/tinybase.js.gz +0 -0
- package/package.json +9 -9
- package/readme.md +2 -2
package/lib/debug/persisters.js
CHANGED
|
@@ -1,7 +1,4 @@
|
|
|
1
|
-
import {promises, watch} from 'fs';
|
|
2
|
-
|
|
3
1
|
const EMPTY_STRING = '';
|
|
4
|
-
const UTF8 = 'utf8';
|
|
5
2
|
|
|
6
3
|
const isUndefined = (thing) => thing == void 0;
|
|
7
4
|
const ifNotUndefined = (value, then, otherwise) =>
|
|
@@ -14,11 +11,10 @@ const createCustomPersister = (
|
|
|
14
11
|
store,
|
|
15
12
|
getPersisted,
|
|
16
13
|
setPersisted,
|
|
17
|
-
|
|
18
|
-
|
|
14
|
+
addPersisterListener,
|
|
15
|
+
delPersisterListener,
|
|
19
16
|
) => {
|
|
20
|
-
let
|
|
21
|
-
let valuesListenerId;
|
|
17
|
+
let listenerId;
|
|
22
18
|
let loadSave = 0;
|
|
23
19
|
let loads = 0;
|
|
24
20
|
let saves = 0;
|
|
@@ -36,9 +32,7 @@ const createCustomPersister = (
|
|
|
36
32
|
if (!isUndefined(body) && body != EMPTY_STRING) {
|
|
37
33
|
store.setJson(body);
|
|
38
34
|
} else {
|
|
39
|
-
store.
|
|
40
|
-
store.setTables(initialTables).setValues(initialValues),
|
|
41
|
-
);
|
|
35
|
+
store.setContent([initialTables, initialValues]);
|
|
42
36
|
}
|
|
43
37
|
loadSave = 0;
|
|
44
38
|
}
|
|
@@ -48,12 +42,26 @@ const createCustomPersister = (
|
|
|
48
42
|
persister.stopAutoLoad();
|
|
49
43
|
await persister.load(initialTables, initialValues);
|
|
50
44
|
listening = true;
|
|
51
|
-
listeningHandle =
|
|
45
|
+
listeningHandle = addPersisterListener(async (content) => {
|
|
46
|
+
if (isUndefined(content)) {
|
|
47
|
+
await persister.load();
|
|
48
|
+
} else {
|
|
49
|
+
/* istanbul ignore else */
|
|
50
|
+
if (loadSave != 2) {
|
|
51
|
+
loadSave = 1;
|
|
52
|
+
{
|
|
53
|
+
loads++;
|
|
54
|
+
}
|
|
55
|
+
store.setContent(content);
|
|
56
|
+
loadSave = 0;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
});
|
|
52
60
|
return persister;
|
|
53
61
|
},
|
|
54
62
|
stopAutoLoad: () => {
|
|
55
63
|
if (listening) {
|
|
56
|
-
|
|
64
|
+
delPersisterListener(listeningHandle);
|
|
57
65
|
listeningHandle = void 0;
|
|
58
66
|
listening = false;
|
|
59
67
|
}
|
|
@@ -66,20 +74,18 @@ const createCustomPersister = (
|
|
|
66
74
|
{
|
|
67
75
|
saves++;
|
|
68
76
|
}
|
|
69
|
-
await setPersisted(store.
|
|
77
|
+
await setPersisted(store.getContent);
|
|
70
78
|
loadSave = 0;
|
|
71
79
|
}
|
|
72
80
|
return persister;
|
|
73
81
|
},
|
|
74
82
|
startAutoSave: async () => {
|
|
75
83
|
await persister.stopAutoSave().save();
|
|
76
|
-
|
|
77
|
-
valuesListenerId = store.addValuesListener(persister.save);
|
|
84
|
+
listenerId = store.addDidFinishTransactionListener(persister.save);
|
|
78
85
|
return persister;
|
|
79
86
|
},
|
|
80
87
|
stopAutoSave: () => {
|
|
81
|
-
ifNotUndefined(
|
|
82
|
-
ifNotUndefined(valuesListenerId, store.delListener);
|
|
88
|
+
ifNotUndefined(listenerId, store.delListener);
|
|
83
89
|
return persister;
|
|
84
90
|
},
|
|
85
91
|
getStore: () => store,
|
|
@@ -89,103 +95,4 @@ const createCustomPersister = (
|
|
|
89
95
|
return objFreeze(persister);
|
|
90
96
|
};
|
|
91
97
|
|
|
92
|
-
|
|
93
|
-
const WINDOW = globalThis.window;
|
|
94
|
-
const getStoragePersister = (store, storageName, storage) => {
|
|
95
|
-
const getPersisted = async () => storage.getItem(storageName);
|
|
96
|
-
const setPersisted = async (json) => storage.setItem(storageName, json);
|
|
97
|
-
const startListeningToPersisted = (didChange) => {
|
|
98
|
-
const listener = (event) => {
|
|
99
|
-
if (event.storageArea === storage && event.key === storageName) {
|
|
100
|
-
didChange();
|
|
101
|
-
}
|
|
102
|
-
};
|
|
103
|
-
WINDOW.addEventListener(STORAGE, listener);
|
|
104
|
-
return listener;
|
|
105
|
-
};
|
|
106
|
-
const stopListeningToPersisted = (listener) =>
|
|
107
|
-
WINDOW.removeEventListener(STORAGE, listener);
|
|
108
|
-
return createCustomPersister(
|
|
109
|
-
store,
|
|
110
|
-
getPersisted,
|
|
111
|
-
setPersisted,
|
|
112
|
-
startListeningToPersisted,
|
|
113
|
-
stopListeningToPersisted,
|
|
114
|
-
);
|
|
115
|
-
};
|
|
116
|
-
const createLocalPersister = (store, storageName) =>
|
|
117
|
-
getStoragePersister(store, storageName, localStorage);
|
|
118
|
-
const createSessionPersister = (store, storageName) =>
|
|
119
|
-
getStoragePersister(store, storageName, sessionStorage);
|
|
120
|
-
|
|
121
|
-
const createFilePersister = (store, filePath) => {
|
|
122
|
-
const getPersisted = async () => {
|
|
123
|
-
try {
|
|
124
|
-
return await promises.readFile(filePath, UTF8);
|
|
125
|
-
} catch {}
|
|
126
|
-
};
|
|
127
|
-
const setPersisted = async (json) => {
|
|
128
|
-
try {
|
|
129
|
-
await promises.writeFile(filePath, json, UTF8);
|
|
130
|
-
} catch {}
|
|
131
|
-
};
|
|
132
|
-
const startListeningToPersisted = (didChange) => watch(filePath, didChange);
|
|
133
|
-
const stopListeningToPersisted = (watcher) => watcher?.close();
|
|
134
|
-
return createCustomPersister(
|
|
135
|
-
store,
|
|
136
|
-
getPersisted,
|
|
137
|
-
setPersisted,
|
|
138
|
-
startListeningToPersisted,
|
|
139
|
-
stopListeningToPersisted,
|
|
140
|
-
);
|
|
141
|
-
};
|
|
142
|
-
|
|
143
|
-
const getETag = (response) => response.headers.get('ETag');
|
|
144
|
-
const createRemotePersister = (
|
|
145
|
-
store,
|
|
146
|
-
loadUrl,
|
|
147
|
-
saveUrl,
|
|
148
|
-
autoLoadIntervalSeconds,
|
|
149
|
-
) => {
|
|
150
|
-
let lastEtag;
|
|
151
|
-
const getPersisted = async () => {
|
|
152
|
-
const response = await fetch(loadUrl);
|
|
153
|
-
lastEtag = getETag(response);
|
|
154
|
-
return response.text();
|
|
155
|
-
};
|
|
156
|
-
const setPersisted = async (json) =>
|
|
157
|
-
await fetch(saveUrl, {
|
|
158
|
-
method: 'POST',
|
|
159
|
-
headers: {'Content-Type': 'application/json'},
|
|
160
|
-
body: json,
|
|
161
|
-
});
|
|
162
|
-
const startListeningToPersisted = (didChange) =>
|
|
163
|
-
setInterval(async () => {
|
|
164
|
-
const response = await fetch(loadUrl, {method: 'HEAD'});
|
|
165
|
-
const currentEtag = getETag(response);
|
|
166
|
-
if (
|
|
167
|
-
!isUndefined(lastEtag) &&
|
|
168
|
-
!isUndefined(currentEtag) &&
|
|
169
|
-
currentEtag != lastEtag
|
|
170
|
-
) {
|
|
171
|
-
lastEtag = currentEtag;
|
|
172
|
-
didChange();
|
|
173
|
-
}
|
|
174
|
-
}, autoLoadIntervalSeconds * 1e3);
|
|
175
|
-
const stopListeningToPersisted = (interval) => clearInterval(interval);
|
|
176
|
-
return createCustomPersister(
|
|
177
|
-
store,
|
|
178
|
-
getPersisted,
|
|
179
|
-
setPersisted,
|
|
180
|
-
startListeningToPersisted,
|
|
181
|
-
stopListeningToPersisted,
|
|
182
|
-
);
|
|
183
|
-
};
|
|
184
|
-
|
|
185
|
-
export {
|
|
186
|
-
createCustomPersister,
|
|
187
|
-
createFilePersister,
|
|
188
|
-
createLocalPersister,
|
|
189
|
-
createRemotePersister,
|
|
190
|
-
createSessionPersister,
|
|
191
|
-
};
|
|
98
|
+
export {createCustomPersister};
|
package/lib/debug/store.js
CHANGED
|
@@ -822,6 +822,7 @@ const createStore = () => {
|
|
|
822
822
|
transaction(() => actions(...arrayMap(args, id)));
|
|
823
823
|
return store;
|
|
824
824
|
};
|
|
825
|
+
const getContent = () => [getTables(), getValues()];
|
|
825
826
|
const getTables = () =>
|
|
826
827
|
mapToObj(tablesMap, (table) => mapToObj(table, mapToObj));
|
|
827
828
|
const getTableIds = () => mapKeys(tablesMap);
|
|
@@ -867,6 +868,11 @@ const createStore = () => {
|
|
|
867
868
|
const getTablesSchemaJson = () => jsonString(tablesSchemaMap);
|
|
868
869
|
const getValuesSchemaJson = () => jsonString(valuesSchemaMap);
|
|
869
870
|
const getSchemaJson = () => jsonString([tablesSchemaMap, valuesSchemaMap]);
|
|
871
|
+
const setContent = ([tables, values]) =>
|
|
872
|
+
fluentTransaction(() => {
|
|
873
|
+
setTables(tables);
|
|
874
|
+
setValues(values);
|
|
875
|
+
});
|
|
870
876
|
const setTables = (tables) =>
|
|
871
877
|
fluentTransaction(() =>
|
|
872
878
|
validateTables(tables) ? setValidTables(tables) : 0,
|
|
@@ -1099,32 +1105,36 @@ const createStore = () => {
|
|
|
1099
1105
|
callKeyedValuesListenersForChanges(1);
|
|
1100
1106
|
}
|
|
1101
1107
|
transactions = -1;
|
|
1102
|
-
|
|
1103
|
-
doRollback
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
|
|
1108
|
+
let transactionChanges =
|
|
1109
|
+
doRollback ||
|
|
1110
|
+
!collIsEmpty(finishTransactionListeners[0]) ||
|
|
1111
|
+
!collIsEmpty(finishTransactionListeners[1])
|
|
1112
|
+
? [
|
|
1107
1113
|
mapToObj(
|
|
1108
|
-
|
|
1109
|
-
(
|
|
1114
|
+
changedCells,
|
|
1115
|
+
(table) =>
|
|
1110
1116
|
mapToObj(
|
|
1111
|
-
|
|
1112
|
-
(
|
|
1113
|
-
|
|
1117
|
+
table,
|
|
1118
|
+
(row) =>
|
|
1119
|
+
mapToObj(
|
|
1120
|
+
row,
|
|
1121
|
+
(cells) => [...cells],
|
|
1122
|
+
([oldCell, newCell]) => oldCell === newCell,
|
|
1123
|
+
),
|
|
1124
|
+
objIsEmpty,
|
|
1114
1125
|
),
|
|
1115
1126
|
objIsEmpty,
|
|
1116
1127
|
),
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
|
|
1127
|
-
) {
|
|
1128
|
+
mapToObj(invalidCells, (map) => mapToObj(map, mapToObj)),
|
|
1129
|
+
mapToObj(
|
|
1130
|
+
changedValues,
|
|
1131
|
+
(values) => [...values],
|
|
1132
|
+
([oldValue, newValue]) => oldValue === newValue,
|
|
1133
|
+
),
|
|
1134
|
+
mapToObj(invalidValues),
|
|
1135
|
+
]
|
|
1136
|
+
: [{}, {}, {}, {}];
|
|
1137
|
+
if (doRollback?.(...transactionChanges)) {
|
|
1128
1138
|
transactions = 1;
|
|
1129
1139
|
collForEach(changedCells, (table, tableId) =>
|
|
1130
1140
|
collForEach(table, (row, rowId) =>
|
|
@@ -1138,12 +1148,14 @@ const createStore = () => {
|
|
|
1138
1148
|
);
|
|
1139
1149
|
transactions = -1;
|
|
1140
1150
|
cellsTouched = valuesTouched = false;
|
|
1151
|
+
transactionChanges = [{}, {}, {}, {}];
|
|
1141
1152
|
}
|
|
1142
1153
|
callListeners(
|
|
1143
1154
|
finishTransactionListeners[0],
|
|
1144
1155
|
void 0,
|
|
1145
1156
|
cellsTouched,
|
|
1146
1157
|
valuesTouched,
|
|
1158
|
+
...transactionChanges,
|
|
1147
1159
|
);
|
|
1148
1160
|
callInvalidCellListeners(0);
|
|
1149
1161
|
if (cellsTouched) {
|
|
@@ -1158,6 +1170,7 @@ const createStore = () => {
|
|
|
1158
1170
|
void 0,
|
|
1159
1171
|
cellsTouched,
|
|
1160
1172
|
valuesTouched,
|
|
1173
|
+
...transactionChanges,
|
|
1161
1174
|
);
|
|
1162
1175
|
transactions = 0;
|
|
1163
1176
|
arrayForEach(
|
|
@@ -1266,6 +1279,7 @@ const createStore = () => {
|
|
|
1266
1279
|
transaction: pairCollSize2(finishTransactionListeners),
|
|
1267
1280
|
});
|
|
1268
1281
|
const store = {
|
|
1282
|
+
getContent,
|
|
1269
1283
|
getTables,
|
|
1270
1284
|
getTableIds,
|
|
1271
1285
|
getTable,
|
|
@@ -1289,6 +1303,7 @@ const createStore = () => {
|
|
|
1289
1303
|
getTablesSchemaJson,
|
|
1290
1304
|
getValuesSchemaJson,
|
|
1291
1305
|
getSchemaJson,
|
|
1306
|
+
setContent,
|
|
1292
1307
|
setTables,
|
|
1293
1308
|
setTable,
|
|
1294
1309
|
setRow,
|
package/lib/debug/tinybase.js
CHANGED
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
import {promises, watch} from 'fs';
|
|
2
|
-
|
|
3
1
|
const getTypeOf = (thing) => typeof thing;
|
|
4
2
|
const EMPTY_STRING = '';
|
|
5
3
|
const STRING = getTypeOf(EMPTY_STRING);
|
|
@@ -8,7 +6,6 @@ const NUMBER = getTypeOf(0);
|
|
|
8
6
|
const FUNCTION = getTypeOf(getTypeOf);
|
|
9
7
|
const TYPE = 'type';
|
|
10
8
|
const DEFAULT = 'default';
|
|
11
|
-
const UTF8 = 'utf8';
|
|
12
9
|
const SUM = 'sum';
|
|
13
10
|
const AVG = 'avg';
|
|
14
11
|
const MIN = 'min';
|
|
@@ -1016,11 +1013,10 @@ const createCustomPersister = (
|
|
|
1016
1013
|
store,
|
|
1017
1014
|
getPersisted,
|
|
1018
1015
|
setPersisted,
|
|
1019
|
-
|
|
1020
|
-
|
|
1016
|
+
addPersisterListener,
|
|
1017
|
+
delPersisterListener,
|
|
1021
1018
|
) => {
|
|
1022
|
-
let
|
|
1023
|
-
let valuesListenerId;
|
|
1019
|
+
let listenerId;
|
|
1024
1020
|
let loadSave = 0;
|
|
1025
1021
|
let loads = 0;
|
|
1026
1022
|
let saves = 0;
|
|
@@ -1038,9 +1034,7 @@ const createCustomPersister = (
|
|
|
1038
1034
|
if (!isUndefined(body) && body != EMPTY_STRING) {
|
|
1039
1035
|
store.setJson(body);
|
|
1040
1036
|
} else {
|
|
1041
|
-
store.
|
|
1042
|
-
store.setTables(initialTables).setValues(initialValues),
|
|
1043
|
-
);
|
|
1037
|
+
store.setContent([initialTables, initialValues]);
|
|
1044
1038
|
}
|
|
1045
1039
|
loadSave = 0;
|
|
1046
1040
|
}
|
|
@@ -1050,12 +1044,26 @@ const createCustomPersister = (
|
|
|
1050
1044
|
persister.stopAutoLoad();
|
|
1051
1045
|
await persister.load(initialTables, initialValues);
|
|
1052
1046
|
listening = true;
|
|
1053
|
-
listeningHandle =
|
|
1047
|
+
listeningHandle = addPersisterListener(async (content) => {
|
|
1048
|
+
if (isUndefined(content)) {
|
|
1049
|
+
await persister.load();
|
|
1050
|
+
} else {
|
|
1051
|
+
/* istanbul ignore else */
|
|
1052
|
+
if (loadSave != 2) {
|
|
1053
|
+
loadSave = 1;
|
|
1054
|
+
{
|
|
1055
|
+
loads++;
|
|
1056
|
+
}
|
|
1057
|
+
store.setContent(content);
|
|
1058
|
+
loadSave = 0;
|
|
1059
|
+
}
|
|
1060
|
+
}
|
|
1061
|
+
});
|
|
1054
1062
|
return persister;
|
|
1055
1063
|
},
|
|
1056
1064
|
stopAutoLoad: () => {
|
|
1057
1065
|
if (listening) {
|
|
1058
|
-
|
|
1066
|
+
delPersisterListener(listeningHandle);
|
|
1059
1067
|
listeningHandle = void 0;
|
|
1060
1068
|
listening = false;
|
|
1061
1069
|
}
|
|
@@ -1068,20 +1076,18 @@ const createCustomPersister = (
|
|
|
1068
1076
|
{
|
|
1069
1077
|
saves++;
|
|
1070
1078
|
}
|
|
1071
|
-
await setPersisted(store.
|
|
1079
|
+
await setPersisted(store.getContent);
|
|
1072
1080
|
loadSave = 0;
|
|
1073
1081
|
}
|
|
1074
1082
|
return persister;
|
|
1075
1083
|
},
|
|
1076
1084
|
startAutoSave: async () => {
|
|
1077
1085
|
await persister.stopAutoSave().save();
|
|
1078
|
-
|
|
1079
|
-
valuesListenerId = store.addValuesListener(persister.save);
|
|
1086
|
+
listenerId = store.addDidFinishTransactionListener(persister.save);
|
|
1080
1087
|
return persister;
|
|
1081
1088
|
},
|
|
1082
1089
|
stopAutoSave: () => {
|
|
1083
|
-
ifNotUndefined(
|
|
1084
|
-
ifNotUndefined(valuesListenerId, store.delListener);
|
|
1090
|
+
ifNotUndefined(listenerId, store.delListener);
|
|
1085
1091
|
return persister;
|
|
1086
1092
|
},
|
|
1087
1093
|
getStore: () => store,
|
|
@@ -1091,99 +1097,6 @@ const createCustomPersister = (
|
|
|
1091
1097
|
return objFreeze(persister);
|
|
1092
1098
|
};
|
|
1093
1099
|
|
|
1094
|
-
const STORAGE = 'storage';
|
|
1095
|
-
const WINDOW = globalThis.window;
|
|
1096
|
-
const getStoragePersister = (store, storageName, storage) => {
|
|
1097
|
-
const getPersisted = async () => storage.getItem(storageName);
|
|
1098
|
-
const setPersisted = async (json) => storage.setItem(storageName, json);
|
|
1099
|
-
const startListeningToPersisted = (didChange) => {
|
|
1100
|
-
const listener = (event) => {
|
|
1101
|
-
if (event.storageArea === storage && event.key === storageName) {
|
|
1102
|
-
didChange();
|
|
1103
|
-
}
|
|
1104
|
-
};
|
|
1105
|
-
WINDOW.addEventListener(STORAGE, listener);
|
|
1106
|
-
return listener;
|
|
1107
|
-
};
|
|
1108
|
-
const stopListeningToPersisted = (listener) =>
|
|
1109
|
-
WINDOW.removeEventListener(STORAGE, listener);
|
|
1110
|
-
return createCustomPersister(
|
|
1111
|
-
store,
|
|
1112
|
-
getPersisted,
|
|
1113
|
-
setPersisted,
|
|
1114
|
-
startListeningToPersisted,
|
|
1115
|
-
stopListeningToPersisted,
|
|
1116
|
-
);
|
|
1117
|
-
};
|
|
1118
|
-
const createLocalPersister = (store, storageName) =>
|
|
1119
|
-
getStoragePersister(store, storageName, localStorage);
|
|
1120
|
-
const createSessionPersister = (store, storageName) =>
|
|
1121
|
-
getStoragePersister(store, storageName, sessionStorage);
|
|
1122
|
-
|
|
1123
|
-
const createFilePersister = (store, filePath) => {
|
|
1124
|
-
const getPersisted = async () => {
|
|
1125
|
-
try {
|
|
1126
|
-
return await promises.readFile(filePath, UTF8);
|
|
1127
|
-
} catch {}
|
|
1128
|
-
};
|
|
1129
|
-
const setPersisted = async (json) => {
|
|
1130
|
-
try {
|
|
1131
|
-
await promises.writeFile(filePath, json, UTF8);
|
|
1132
|
-
} catch {}
|
|
1133
|
-
};
|
|
1134
|
-
const startListeningToPersisted = (didChange) => watch(filePath, didChange);
|
|
1135
|
-
const stopListeningToPersisted = (watcher) => watcher?.close();
|
|
1136
|
-
return createCustomPersister(
|
|
1137
|
-
store,
|
|
1138
|
-
getPersisted,
|
|
1139
|
-
setPersisted,
|
|
1140
|
-
startListeningToPersisted,
|
|
1141
|
-
stopListeningToPersisted,
|
|
1142
|
-
);
|
|
1143
|
-
};
|
|
1144
|
-
|
|
1145
|
-
const getETag = (response) => response.headers.get('ETag');
|
|
1146
|
-
const createRemotePersister = (
|
|
1147
|
-
store,
|
|
1148
|
-
loadUrl,
|
|
1149
|
-
saveUrl,
|
|
1150
|
-
autoLoadIntervalSeconds,
|
|
1151
|
-
) => {
|
|
1152
|
-
let lastEtag;
|
|
1153
|
-
const getPersisted = async () => {
|
|
1154
|
-
const response = await fetch(loadUrl);
|
|
1155
|
-
lastEtag = getETag(response);
|
|
1156
|
-
return response.text();
|
|
1157
|
-
};
|
|
1158
|
-
const setPersisted = async (json) =>
|
|
1159
|
-
await fetch(saveUrl, {
|
|
1160
|
-
method: 'POST',
|
|
1161
|
-
headers: {'Content-Type': 'application/json'},
|
|
1162
|
-
body: json,
|
|
1163
|
-
});
|
|
1164
|
-
const startListeningToPersisted = (didChange) =>
|
|
1165
|
-
setInterval(async () => {
|
|
1166
|
-
const response = await fetch(loadUrl, {method: 'HEAD'});
|
|
1167
|
-
const currentEtag = getETag(response);
|
|
1168
|
-
if (
|
|
1169
|
-
!isUndefined(lastEtag) &&
|
|
1170
|
-
!isUndefined(currentEtag) &&
|
|
1171
|
-
currentEtag != lastEtag
|
|
1172
|
-
) {
|
|
1173
|
-
lastEtag = currentEtag;
|
|
1174
|
-
didChange();
|
|
1175
|
-
}
|
|
1176
|
-
}, autoLoadIntervalSeconds * 1e3);
|
|
1177
|
-
const stopListeningToPersisted = (interval) => clearInterval(interval);
|
|
1178
|
-
return createCustomPersister(
|
|
1179
|
-
store,
|
|
1180
|
-
getPersisted,
|
|
1181
|
-
setPersisted,
|
|
1182
|
-
startListeningToPersisted,
|
|
1183
|
-
stopListeningToPersisted,
|
|
1184
|
-
);
|
|
1185
|
-
};
|
|
1186
|
-
|
|
1187
1100
|
const createQueries = getCreateFunction((store) => {
|
|
1188
1101
|
const createStore = store.createStore;
|
|
1189
1102
|
const [
|
|
@@ -2384,6 +2297,7 @@ const createStore = () => {
|
|
|
2384
2297
|
transaction(() => actions(...arrayMap(args, id)));
|
|
2385
2298
|
return store;
|
|
2386
2299
|
};
|
|
2300
|
+
const getContent = () => [getTables(), getValues()];
|
|
2387
2301
|
const getTables = () =>
|
|
2388
2302
|
mapToObj(tablesMap, (table) => mapToObj(table, mapToObj));
|
|
2389
2303
|
const getTableIds = () => mapKeys(tablesMap);
|
|
@@ -2429,6 +2343,11 @@ const createStore = () => {
|
|
|
2429
2343
|
const getTablesSchemaJson = () => jsonString(tablesSchemaMap);
|
|
2430
2344
|
const getValuesSchemaJson = () => jsonString(valuesSchemaMap);
|
|
2431
2345
|
const getSchemaJson = () => jsonString([tablesSchemaMap, valuesSchemaMap]);
|
|
2346
|
+
const setContent = ([tables, values]) =>
|
|
2347
|
+
fluentTransaction(() => {
|
|
2348
|
+
setTables(tables);
|
|
2349
|
+
setValues(values);
|
|
2350
|
+
});
|
|
2432
2351
|
const setTables = (tables) =>
|
|
2433
2352
|
fluentTransaction(() =>
|
|
2434
2353
|
validateTables(tables) ? setValidTables(tables) : 0,
|
|
@@ -2661,32 +2580,36 @@ const createStore = () => {
|
|
|
2661
2580
|
callKeyedValuesListenersForChanges(1);
|
|
2662
2581
|
}
|
|
2663
2582
|
transactions = -1;
|
|
2664
|
-
|
|
2665
|
-
doRollback
|
|
2666
|
-
|
|
2667
|
-
|
|
2668
|
-
|
|
2583
|
+
let transactionChanges =
|
|
2584
|
+
doRollback ||
|
|
2585
|
+
!collIsEmpty(finishTransactionListeners[0]) ||
|
|
2586
|
+
!collIsEmpty(finishTransactionListeners[1])
|
|
2587
|
+
? [
|
|
2669
2588
|
mapToObj(
|
|
2670
|
-
|
|
2671
|
-
(
|
|
2589
|
+
changedCells,
|
|
2590
|
+
(table) =>
|
|
2672
2591
|
mapToObj(
|
|
2673
|
-
|
|
2674
|
-
(
|
|
2675
|
-
|
|
2592
|
+
table,
|
|
2593
|
+
(row) =>
|
|
2594
|
+
mapToObj(
|
|
2595
|
+
row,
|
|
2596
|
+
(cells) => [...cells],
|
|
2597
|
+
([oldCell, newCell]) => oldCell === newCell,
|
|
2598
|
+
),
|
|
2599
|
+
objIsEmpty,
|
|
2676
2600
|
),
|
|
2677
2601
|
objIsEmpty,
|
|
2678
2602
|
),
|
|
2679
|
-
|
|
2680
|
-
|
|
2681
|
-
|
|
2682
|
-
|
|
2683
|
-
|
|
2684
|
-
|
|
2685
|
-
|
|
2686
|
-
|
|
2687
|
-
|
|
2688
|
-
|
|
2689
|
-
) {
|
|
2603
|
+
mapToObj(invalidCells, (map) => mapToObj(map, mapToObj)),
|
|
2604
|
+
mapToObj(
|
|
2605
|
+
changedValues,
|
|
2606
|
+
(values) => [...values],
|
|
2607
|
+
([oldValue, newValue]) => oldValue === newValue,
|
|
2608
|
+
),
|
|
2609
|
+
mapToObj(invalidValues),
|
|
2610
|
+
]
|
|
2611
|
+
: [{}, {}, {}, {}];
|
|
2612
|
+
if (doRollback?.(...transactionChanges)) {
|
|
2690
2613
|
transactions = 1;
|
|
2691
2614
|
collForEach(changedCells, (table, tableId) =>
|
|
2692
2615
|
collForEach(table, (row, rowId) =>
|
|
@@ -2700,12 +2623,14 @@ const createStore = () => {
|
|
|
2700
2623
|
);
|
|
2701
2624
|
transactions = -1;
|
|
2702
2625
|
cellsTouched = valuesTouched = false;
|
|
2626
|
+
transactionChanges = [{}, {}, {}, {}];
|
|
2703
2627
|
}
|
|
2704
2628
|
callListeners(
|
|
2705
2629
|
finishTransactionListeners[0],
|
|
2706
2630
|
void 0,
|
|
2707
2631
|
cellsTouched,
|
|
2708
2632
|
valuesTouched,
|
|
2633
|
+
...transactionChanges,
|
|
2709
2634
|
);
|
|
2710
2635
|
callInvalidCellListeners(0);
|
|
2711
2636
|
if (cellsTouched) {
|
|
@@ -2720,6 +2645,7 @@ const createStore = () => {
|
|
|
2720
2645
|
void 0,
|
|
2721
2646
|
cellsTouched,
|
|
2722
2647
|
valuesTouched,
|
|
2648
|
+
...transactionChanges,
|
|
2723
2649
|
);
|
|
2724
2650
|
transactions = 0;
|
|
2725
2651
|
arrayForEach(
|
|
@@ -2828,6 +2754,7 @@ const createStore = () => {
|
|
|
2828
2754
|
transaction: pairCollSize2(finishTransactionListeners),
|
|
2829
2755
|
});
|
|
2830
2756
|
const store = {
|
|
2757
|
+
getContent,
|
|
2831
2758
|
getTables,
|
|
2832
2759
|
getTableIds,
|
|
2833
2760
|
getTable,
|
|
@@ -2851,6 +2778,7 @@ const createStore = () => {
|
|
|
2851
2778
|
getTablesSchemaJson,
|
|
2852
2779
|
getValuesSchemaJson,
|
|
2853
2780
|
getSchemaJson,
|
|
2781
|
+
setContent,
|
|
2854
2782
|
setTables,
|
|
2855
2783
|
setTable,
|
|
2856
2784
|
setRow,
|
|
@@ -2932,14 +2860,10 @@ const createStore = () => {
|
|
|
2932
2860
|
export {
|
|
2933
2861
|
createCheckpoints,
|
|
2934
2862
|
createCustomPersister,
|
|
2935
|
-
createFilePersister,
|
|
2936
2863
|
createIndexes,
|
|
2937
|
-
createLocalPersister,
|
|
2938
2864
|
createMetrics,
|
|
2939
2865
|
createQueries,
|
|
2940
2866
|
createRelationships,
|
|
2941
|
-
createRemotePersister,
|
|
2942
|
-
createSessionPersister,
|
|
2943
2867
|
createStore,
|
|
2944
2868
|
defaultSorter,
|
|
2945
2869
|
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
const t=t=>null==t,e=Object.freeze;var n=(t,e,n)=>new Promise(((o,r)=>{var a=t=>{try{i(n.next(t))}catch(t){r(t)}},s=t=>{try{i(n.throw(t))}catch(t){r(t)}},i=t=>t.done?o(t.value):Promise.resolve(t.value).then(a,s);i((n=n.apply(t,e)).next())})),o=(t,e,n)=>new Promise(((o,r)=>{var a=t=>{try{i(n.next(t))}catch(t){r(t)}},s=t=>{try{i(n.throw(t))}catch(t){r(t)}},i=t=>t.done?o(t.value):Promise.resolve(t.value).then(a,s);i((n=n.apply(t,e)).next())}));const r=globalThis.window,a=(a,s,i)=>((a,l,u,v,d)=>{let c,y,p=0,f=!1;const g={load:(e,r)=>n(void 0,null,(function*(){if(2!=p){p=1;const n=yield o(void 0,null,(function*(){return i.getItem(s)}));t(n)||""==n?a.setContent([e,r]):a.setJson(n),p=0}return g})),startAutoLoad:(e,o)=>n(void 0,null,(function*(){return g.stopAutoLoad(),yield g.load(e,o),f=!0,y=(t=>{const e=e=>{if(e.storageArea===i&&e.key===s){let n;try{n=JSON.parse(e.newValue)}catch(t){}t(n)}};return r.addEventListener("storage",e),e})((e=>n(void 0,null,(function*(){t(e)?yield g.load():2!=p&&(p=1,a.setContent(e),p=0)})))),g})),stopAutoLoad:()=>{return f&&(t=y,r.removeEventListener("storage",t),y=void 0,f=!1),g;var t},save:()=>n(void 0,null,(function*(){return 1!=p&&(p=2,yield(t=a.getContent,o(void 0,null,(function*(){return i.setItem(s,(e=t(),JSON.stringify(e,((t,e)=>{return e instanceof Map?(n=(t,[e,n])=>(t[e]=n,t),o={},[...e].reduce(n,o)):e;var n,o}))));var e}))),p=0),g;var t})),startAutoSave:()=>n(void 0,null,(function*(){return yield g.stopAutoSave().save(),c=a.addDidFinishTransactionListener(g.save),g})),stopAutoSave:()=>{var e,n;return e=c,n=a.delListener,!!t(e)||n(e),g},getStore:()=>a,destroy:()=>g.stopAutoLoad().stopAutoSave(),getStats:()=>({})};return e(g)})(a),s=(t,e)=>a(t,e,localStorage),i=(t,e)=>a(t,e,sessionStorage);export{s as createLocalPersister,i as createSessionPersister};
|
|
Binary file
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{readFile as t,writeFile as e}from"fs/promises";import{watch as o}from"fs";const n=t=>null==t,r=Object.freeze;var a=(t,e,o)=>new Promise(((n,r)=>{var a=t=>{try{i(o.next(t))}catch(t){r(t)}},u=t=>{try{i(o.throw(t))}catch(t){r(t)}},i=t=>t.done?n(t.value):Promise.resolve(t.value).then(a,u);i((o=o.apply(t,e)).next())})),u=(t,e,o)=>new Promise(((n,r)=>{var a=t=>{try{i(o.next(t))}catch(t){r(t)}},u=t=>{try{i(o.throw(t))}catch(t){r(t)}},i=t=>t.done?n(t.value):Promise.resolve(t.value).then(a,u);i((o=o.apply(t,e)).next())}));const i=(i,l)=>((i,s,d,v,c)=>{let f,y,p=0,h=!1;const m={load:(e,o)=>a(void 0,null,(function*(){if(2!=p){p=1;const r=yield u(void 0,null,(function*(){try{return yield t(l,"utf8")}catch(t){}}));n(r)||""==r?i.setContent([e,o]):i.setJson(r),p=0}return m})),startAutoLoad:(t,e)=>a(void 0,null,(function*(){return m.stopAutoLoad(),yield m.load(t,e),h=!0,r=t=>a(void 0,null,(function*(){n(t)?yield m.load():2!=p&&(p=1,i.setContent(t),p=0)})),y=o(l,(()=>r())),m;var r})),stopAutoLoad:()=>{return h&&(null==(t=y)||t.close(),y=void 0,h=!1),m;var t},save:()=>a(void 0,null,(function*(){return 1!=p&&(p=2,yield(t=i.getContent,u(void 0,null,(function*(){try{yield e(l,(o=t(),JSON.stringify(o,((t,e)=>{return e instanceof Map?(o=(t,[e,o])=>(t[e]=o,t),n={},[...e].reduce(o,n)):e;var o,n}))),"utf8")}catch(t){}var o}))),p=0),m;var t})),startAutoSave:()=>a(void 0,null,(function*(){return yield m.stopAutoSave().save(),f=i.addDidFinishTransactionListener(m.save),m})),stopAutoSave:()=>{var t,e;return t=f,e=i.delListener,!!n(t)||e(t),m},getStore:()=>i,destroy:()=>m.stopAutoLoad().stopAutoSave(),getStats:()=>({})};return r(m)})(i);export{i as createFilePersister};
|
|
Binary file
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
const t=t=>null==t,e=Object.freeze;var n=(t,e,n)=>new Promise(((o,r)=>{var a=t=>{try{i(n.next(t))}catch(t){r(t)}},l=t=>{try{i(n.throw(t))}catch(t){r(t)}},i=t=>t.done?o(t.value):Promise.resolve(t.value).then(a,l);i((n=n.apply(t,e)).next())})),o=(t,e,n)=>new Promise(((o,r)=>{var a=t=>{try{i(n.next(t))}catch(t){r(t)}},l=t=>{try{i(n.throw(t))}catch(t){r(t)}},i=t=>t.done?o(t.value):Promise.resolve(t.value).then(a,l);i((n=n.apply(t,e)).next())}));const r=t=>t.headers.get("ETag"),a=(a,l,i,u)=>{let s;return((a,d,v,c,y)=>{let h,f,p=0,A=!1;const S={load:(e,i)=>n(void 0,null,(function*(){if(2!=p){p=1;const n=yield o(void 0,null,(function*(){const t=yield fetch(l);return s=r(t),t.text()}));t(n)||""==n?a.setContent([e,i]):a.setJson(n),p=0}return S})),startAutoLoad:(e,i)=>n(void 0,null,(function*(){return S.stopAutoLoad(),yield S.load(e,i),A=!0,d=e=>n(void 0,null,(function*(){t(e)?yield S.load():2!=p&&(p=1,a.setContent(e),p=0)})),f=setInterval((()=>o(void 0,null,(function*(){const e=yield fetch(l,{method:"HEAD"}),n=r(e);t(s)||t(n)||n==s||(s=n,d())}))),1e3*u),S;var d})),stopAutoLoad:()=>(A&&(clearInterval(f),f=void 0,A=!1),S),save:()=>n(void 0,null,(function*(){return 1!=p&&(p=2,yield(t=a.getContent,o(void 0,null,(function*(){return yield fetch(i,{method:"POST",headers:{"Content-Type":"application/json"},body:(e=t(),JSON.stringify(e,((t,e)=>{return e instanceof Map?(n=(t,[e,n])=>(t[e]=n,t),o={},[...e].reduce(n,o)):e;var n,o})))});var e}))),p=0),S;var t})),startAutoSave:()=>n(void 0,null,(function*(){return yield S.stopAutoSave().save(),h=a.addDidFinishTransactionListener(S.save),S})),stopAutoSave:()=>{var e,n;return e=h,n=a.delListener,!!t(e)||n(e),S},getStore:()=>a,destroy:()=>S.stopAutoLoad().stopAutoSave(),getStats:()=>({})};return e(S)})(a)};export{a as createRemotePersister};
|
|
Binary file
|
package/lib/es6/persister-yjs.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
const
|
|
1
|
+
const t=t=>null==t,e=Object.freeze;var n=(t,e,n)=>new Promise(((o,r)=>{var s=t=>{try{u(n.next(t))}catch(t){r(t)}},a=t=>{try{u(n.throw(t))}catch(t){r(t)}},u=t=>t.done?o(t.value):Promise.resolve(t.value).then(s,a);u((n=n.apply(t,e)).next())})),o=(t,e,n)=>new Promise(((o,r)=>{var s=t=>{try{u(n.next(t))}catch(t){r(t)}},a=t=>{try{u(n.throw(t))}catch(t){r(t)}},u=t=>t.done?o(t.value):Promise.resolve(t.value).then(s,a);u((n=n.apply(t,e)).next())}));const r=(r,s)=>{const a=s.getMap("tinybase/store");return((r,s,u,i,l)=>{let v,d,c=0,y=!1;const p={load:(e,s)=>n(void 0,null,(function*(){if(2!=c){c=1;const n=yield o(void 0,null,(function*(){return a.get("json")}));t(n)||""==n?r.setContent([e,s]):r.setJson(n),c=0}return p})),startAutoLoad:(e,o)=>n(void 0,null,(function*(){return p.stopAutoLoad(),yield p.load(e,o),y=!0,d=(t=>{const e=()=>t();return a.observe(e),e})((e=>n(void 0,null,(function*(){t(e)?yield p.load():2!=c&&(c=1,r.setContent(e),c=0)})))),p})),stopAutoLoad:()=>{return y&&(t=d,a.unobserve(t),d=void 0,y=!1),p;var t},save:()=>n(void 0,null,(function*(){return 1!=c&&(c=2,yield(t=r.getContent,o(void 0,null,(function*(){a.set("json",JSON.stringify(t()))}))),c=0),p;var t})),startAutoSave:()=>n(void 0,null,(function*(){return yield p.stopAutoSave().save(),v=r.addDidFinishTransactionListener(p.save),p})),stopAutoSave:()=>{var e,n;return e=v,n=r.delListener,!!t(e)||n(e),p},getStore:()=>r,destroy:()=>p.stopAutoLoad().stopAutoSave(),getStats:()=>({})};return e(p)})(r)};export{r as createYjsPersister};
|
|
Binary file
|