tinybase 0.0.0 → 0.9.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/LICENSE +21 -0
- package/lib/checkpoints.d.ts +876 -0
- package/lib/checkpoints.js +1 -0
- package/lib/checkpoints.js.gz +0 -0
- package/lib/common.d.ts +59 -0
- package/lib/debug/checkpoints.d.ts +876 -0
- package/lib/debug/checkpoints.js +326 -0
- package/lib/debug/common.d.ts +59 -0
- package/lib/debug/indexes.d.ts +829 -0
- package/lib/debug/indexes.js +390 -0
- package/lib/debug/metrics.d.ts +753 -0
- package/lib/debug/metrics.js +391 -0
- package/lib/debug/persisters.d.ts +704 -0
- package/lib/debug/persisters.js +191 -0
- package/lib/debug/relationships.d.ts +1114 -0
- package/lib/debug/relationships.js +418 -0
- package/lib/debug/store.d.ts +2503 -0
- package/lib/debug/store.js +725 -0
- package/lib/debug/tinybase.d.ts +13 -0
- package/lib/debug/tinybase.js +1708 -0
- package/lib/debug/ui-react.d.ts +7158 -0
- package/lib/debug/ui-react.js +1040 -0
- package/lib/indexes.d.ts +829 -0
- package/lib/indexes.js +1 -0
- package/lib/indexes.js.gz +0 -0
- package/lib/metrics.d.ts +753 -0
- package/lib/metrics.js +1 -0
- package/lib/metrics.js.gz +0 -0
- package/lib/persisters.d.ts +704 -0
- package/lib/persisters.js +1 -0
- package/lib/persisters.js.gz +0 -0
- package/lib/relationships.d.ts +1114 -0
- package/lib/relationships.js +1 -0
- package/lib/relationships.js.gz +0 -0
- package/lib/store.d.ts +2503 -0
- package/lib/store.js +1 -0
- package/lib/store.js.gz +0 -0
- package/lib/tinybase.d.ts +13 -0
- package/lib/tinybase.js +1 -0
- package/lib/tinybase.js.gz +0 -0
- package/lib/ui-react.d.ts +7158 -0
- package/lib/ui-react.js +1 -0
- package/lib/ui-react.js.gz +0 -0
- package/lib/umd/checkpoints.js +1 -0
- package/lib/umd/checkpoints.js.gz +0 -0
- package/lib/umd/indexes.js +1 -0
- package/lib/umd/indexes.js.gz +0 -0
- package/lib/umd/metrics.js +1 -0
- package/lib/umd/metrics.js.gz +0 -0
- package/lib/umd/persisters.js +1 -0
- package/lib/umd/persisters.js.gz +0 -0
- package/lib/umd/relationships.js +1 -0
- package/lib/umd/relationships.js.gz +0 -0
- package/lib/umd/store.js +1 -0
- package/lib/umd/store.js.gz +0 -0
- package/lib/umd/tinybase.js +1 -0
- package/lib/umd/tinybase.js.gz +0 -0
- package/lib/umd/ui-react.js +1 -0
- package/lib/umd/ui-react.js.gz +0 -0
- package/package.json +98 -2
- package/readme.md +195 -0
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
import {promises, watch} from 'fs';
|
|
2
|
+
|
|
3
|
+
const UTF8 = 'utf8';
|
|
4
|
+
|
|
5
|
+
const isUndefined = (thing) => thing == void 0;
|
|
6
|
+
const ifNotUndefined = (value, then, otherwise) =>
|
|
7
|
+
isUndefined(value) ? otherwise?.() : then(value);
|
|
8
|
+
|
|
9
|
+
const object = Object;
|
|
10
|
+
const objFreeze = object.freeze;
|
|
11
|
+
|
|
12
|
+
const createCustomPersister = (
|
|
13
|
+
store,
|
|
14
|
+
getPersisted,
|
|
15
|
+
setPersisted,
|
|
16
|
+
startListeningToPersisted,
|
|
17
|
+
stopListeningToPersisted,
|
|
18
|
+
) => {
|
|
19
|
+
let tablesListenerId;
|
|
20
|
+
let loadSave = 0;
|
|
21
|
+
let loads = 0;
|
|
22
|
+
let saves = 0;
|
|
23
|
+
const persister = {
|
|
24
|
+
load: async (initialTables) => {
|
|
25
|
+
/* istanbul ignore else */
|
|
26
|
+
if (loadSave != 2) {
|
|
27
|
+
loadSave = 1;
|
|
28
|
+
{
|
|
29
|
+
loads++;
|
|
30
|
+
}
|
|
31
|
+
const body = await getPersisted();
|
|
32
|
+
if (!isUndefined(body) && body != '') {
|
|
33
|
+
store.setJson(body);
|
|
34
|
+
} else {
|
|
35
|
+
store.setTables(initialTables);
|
|
36
|
+
}
|
|
37
|
+
loadSave = 0;
|
|
38
|
+
}
|
|
39
|
+
return persister;
|
|
40
|
+
},
|
|
41
|
+
startAutoLoad: async (initialTables) => {
|
|
42
|
+
persister.stopAutoLoad();
|
|
43
|
+
await persister.load(initialTables);
|
|
44
|
+
startListeningToPersisted(persister.load);
|
|
45
|
+
return persister;
|
|
46
|
+
},
|
|
47
|
+
stopAutoLoad: () => {
|
|
48
|
+
stopListeningToPersisted();
|
|
49
|
+
return persister;
|
|
50
|
+
},
|
|
51
|
+
save: async () => {
|
|
52
|
+
/* istanbul ignore else */
|
|
53
|
+
if (loadSave != 1) {
|
|
54
|
+
loadSave = 2;
|
|
55
|
+
{
|
|
56
|
+
saves++;
|
|
57
|
+
}
|
|
58
|
+
await setPersisted(store.getJson());
|
|
59
|
+
loadSave = 0;
|
|
60
|
+
}
|
|
61
|
+
return persister;
|
|
62
|
+
},
|
|
63
|
+
startAutoSave: async () => {
|
|
64
|
+
await persister.stopAutoSave().save();
|
|
65
|
+
tablesListenerId = store.addTablesListener(() => persister.save());
|
|
66
|
+
return persister;
|
|
67
|
+
},
|
|
68
|
+
stopAutoSave: () => {
|
|
69
|
+
ifNotUndefined(tablesListenerId, store.delListener);
|
|
70
|
+
return persister;
|
|
71
|
+
},
|
|
72
|
+
getStore: () => store,
|
|
73
|
+
destroy: () => persister.stopAutoLoad().stopAutoSave(),
|
|
74
|
+
getStats: () => ({loads, saves}),
|
|
75
|
+
};
|
|
76
|
+
return objFreeze(persister);
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
const STORAGE = 'storage';
|
|
80
|
+
const WINDOW = globalThis.window;
|
|
81
|
+
const getStoragePersister = (store, storageName, storage) => {
|
|
82
|
+
let listener;
|
|
83
|
+
const getPersisted = async () => storage.getItem(storageName);
|
|
84
|
+
const setPersisted = async (json) => storage.setItem(storageName, json);
|
|
85
|
+
const startListeningToPersisted = (didChange) => {
|
|
86
|
+
listener = (event) => {
|
|
87
|
+
if (event.storageArea === storage && event.key === storageName) {
|
|
88
|
+
didChange();
|
|
89
|
+
}
|
|
90
|
+
};
|
|
91
|
+
WINDOW.addEventListener(STORAGE, listener);
|
|
92
|
+
};
|
|
93
|
+
const stopListeningToPersisted = () => {
|
|
94
|
+
WINDOW.removeEventListener(STORAGE, listener);
|
|
95
|
+
listener = void 0;
|
|
96
|
+
};
|
|
97
|
+
return createCustomPersister(
|
|
98
|
+
store,
|
|
99
|
+
getPersisted,
|
|
100
|
+
setPersisted,
|
|
101
|
+
startListeningToPersisted,
|
|
102
|
+
stopListeningToPersisted,
|
|
103
|
+
);
|
|
104
|
+
};
|
|
105
|
+
const createLocalPersister = (store, storageName) =>
|
|
106
|
+
getStoragePersister(store, storageName, localStorage);
|
|
107
|
+
const createSessionPersister = (store, storageName) =>
|
|
108
|
+
getStoragePersister(store, storageName, sessionStorage);
|
|
109
|
+
|
|
110
|
+
const createFilePersister = (store, filePath) => {
|
|
111
|
+
let watcher;
|
|
112
|
+
const getPersisted = async () => {
|
|
113
|
+
try {
|
|
114
|
+
return await promises.readFile(filePath, UTF8);
|
|
115
|
+
} catch {}
|
|
116
|
+
};
|
|
117
|
+
const setPersisted = async (json) => {
|
|
118
|
+
try {
|
|
119
|
+
await promises.writeFile(filePath, json, UTF8);
|
|
120
|
+
} catch {}
|
|
121
|
+
};
|
|
122
|
+
const startListeningToPersisted = (didChange) => {
|
|
123
|
+
watcher = watch(filePath, didChange);
|
|
124
|
+
};
|
|
125
|
+
const stopListeningToPersisted = () => {
|
|
126
|
+
watcher?.close();
|
|
127
|
+
watcher = void 0;
|
|
128
|
+
};
|
|
129
|
+
return createCustomPersister(
|
|
130
|
+
store,
|
|
131
|
+
getPersisted,
|
|
132
|
+
setPersisted,
|
|
133
|
+
startListeningToPersisted,
|
|
134
|
+
stopListeningToPersisted,
|
|
135
|
+
);
|
|
136
|
+
};
|
|
137
|
+
|
|
138
|
+
const getETag = (response) => response.headers.get('ETag');
|
|
139
|
+
const createRemotePersister = (
|
|
140
|
+
store,
|
|
141
|
+
loadUrl,
|
|
142
|
+
saveUrl,
|
|
143
|
+
autoLoadIntervalSeconds,
|
|
144
|
+
) => {
|
|
145
|
+
let interval;
|
|
146
|
+
let lastEtag;
|
|
147
|
+
const getPersisted = async () => {
|
|
148
|
+
const response = await fetch(loadUrl);
|
|
149
|
+
lastEtag = getETag(response);
|
|
150
|
+
return response.text();
|
|
151
|
+
};
|
|
152
|
+
const setPersisted = async (json) =>
|
|
153
|
+
await fetch(saveUrl, {
|
|
154
|
+
method: 'POST',
|
|
155
|
+
headers: {'Content-Type': 'application/json'},
|
|
156
|
+
body: json,
|
|
157
|
+
});
|
|
158
|
+
const startListeningToPersisted = (didChange) => {
|
|
159
|
+
interval = setInterval(async () => {
|
|
160
|
+
const response = await fetch(loadUrl, {method: 'HEAD'});
|
|
161
|
+
const currentEtag = getETag(response);
|
|
162
|
+
if (
|
|
163
|
+
!isUndefined(lastEtag) &&
|
|
164
|
+
!isUndefined(currentEtag) &&
|
|
165
|
+
currentEtag != lastEtag
|
|
166
|
+
) {
|
|
167
|
+
lastEtag = currentEtag;
|
|
168
|
+
didChange();
|
|
169
|
+
}
|
|
170
|
+
}, autoLoadIntervalSeconds * 1e3);
|
|
171
|
+
};
|
|
172
|
+
const stopListeningToPersisted = () => {
|
|
173
|
+
ifNotUndefined(interval, clearInterval);
|
|
174
|
+
interval = void 0;
|
|
175
|
+
};
|
|
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
|
+
};
|