tinybase 4.4.0 → 4.4.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/persisters/persister-partykit-server.cjs +1 -1
- package/lib/cjs/persisters/persister-partykit-server.cjs.gz +0 -0
- package/lib/cjs-es6/persisters/persister-partykit-server.cjs +1 -1
- package/lib/cjs-es6/persisters/persister-partykit-server.cjs.gz +0 -0
- package/lib/debug/persisters/persister-partykit-server.js +35 -21
- package/lib/es6/persisters/persister-partykit-server.js +1 -1
- package/lib/es6/persisters/persister-partykit-server.js.gz +0 -0
- package/lib/persisters/persister-partykit-server.js +1 -1
- package/lib/persisters/persister-partykit-server.js.gz +0 -0
- package/lib/types/persisters/persister-partykit-server.d.ts +58 -2
- package/lib/types/persisters/persister-remote.d.ts +6 -1
- package/lib/types/with-schemas/persisters/persister-partykit-server.d.ts +61 -0
- package/lib/types/with-schemas/persisters/persister-remote.d.ts +6 -1
- package/lib/umd/persisters/persister-partykit-server.js +1 -1
- package/lib/umd/persisters/persister-partykit-server.js.gz +0 -0
- package/lib/umd-es6/persisters/persister-partykit-server.js +1 -1
- package/lib/umd-es6/persisters/persister-partykit-server.js.gz +0 -0
- package/package.json +1 -1
- package/readme.md +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";const t=t=>typeof t,
|
|
1
|
+
"use strict";const t=t=>typeof t,e=t(""),a="t",s=(t,e)=>t.startsWith(e),n=Promise,r=t=>null==t,i=(t,e,a)=>r(t)?a?.():e(t),o=(t,e,a)=>t.slice(e,a),c=t=>t.length,l=async t=>n.all(t),g=(t,e)=>t.map(e),h=(t,...e)=>t.push(...e),u=Object,w=(t=[])=>u.fromEntries(t),f=(t,e)=>g(u.entries(t),(([t,a])=>e(a,t))),y=(t,e,a)=>(((t,e)=>!r(((t,e)=>i(t,(t=>t[e])))(t,e)))(t,e)||(t[e]=a()),t[e]),p=t=>JSON.stringify(t,((t,e)=>e instanceof Map?u.fromEntries([...e]):e)),S=JSON.parse,d=(a,s,n)=>a+s+(t(n)==e?n:p(n)),P=(t,e,a)=>{const n=c(t);return s(e,t)?[e[n],(a?S:String)(o(e,n+1))]:void 0},x=(t,e)=>((t,e)=>t?.forEach(e))(t,((t,a)=>e(a,t))),m="hasStore",D=w(g(["Origin","Methods","Headers"],(t=>["Access-Control-Allow-"+t,"*"]))),R=async(t,e="")=>!!await t.get(e+m),b=async(t,e="")=>{const s={},n={};return x(await t.list(),((t,r)=>i(P(e,t),(([t,e])=>{if(t==a){const[t,a,n]=S("["+e+"]");y(y(s,t,w),a,w)[n]=r}else"v"==t&&(n[e]=r)})))),[s,n]},T=async(t,e,n,i)=>{const o=t.party.storage,g=t.config.storagePrefix,u={[g+m]:1},w=[],y=[];await l(f(e[0],(async(e,s)=>r(e)?!n&&t.canDelTable(s,i)&&((t,...e)=>t.unshift(...e))(y,v(g,a,s)):t.canSetTable(s,n,i)&&await l(f(e,(async(e,c)=>r(e)?!n&&t.canDelRow(s,c,i)&&h(y,v(g,a,s,c)):t.canSetRow(s,c,n,i)&&await l(f(e,(async(e,l)=>{const f=[s,c,l],y=v(g,a,...f);r(e)?!n&&t.canDelCell(...f,i)&&h(w,y):t.canSetCell(...f,e,n,i,await o.get(y))&&(u[y]=e)}))))))))),await l(f(e[1],(async(e,a)=>{const s=g+"v"+a;r(e)?!n&&t.canDelValue(a,i)&&h(w,s):t.canSetValue(a,e,n,i,await o.get(s))&&(u[s]=e)}))),0!=c(y)&&x(await o.list(),(t=>y.every((e=>!s(t,e)||h(w,t)&&0)))),await o.delete(w),await o.put(u)},v=(t,e,...a)=>d(t,e,o(p(a),1,-1)),C=async(t,e,a=null)=>new Response(a,{status:e,headers:t.config.responseHeaders});exports.TinyBasePartyKitServer=class{constructor(t){this.party=t,this.config={},this.config.storePath??="/store",this.config.messagePrefix??="",this.config.storagePrefix??="",this.config.responseHeaders??=D}async onRequest(t){const{party:{storage:e},config:{storePath:a,storagePrefix:s}}=this;if(new URL(t.url).pathname.endsWith(a)){const a=await R(e,s),n=await t.text();return"PUT"==t.method?a?C(this,205):(await T(this,S(n),!0,t),C(this,201)):C(this,200,a?p(await b(e,s)):"")}return C(this,404)}async onMessage(t,e){const{party:{storage:a,broadcast:s},config:{messagePrefix:n,storagePrefix:r}}=this;await i(P(n,t,1),(async([t,i])=>{"s"==t&&await R(a,r)&&(await T(this,i,!1,e),s(d(n,"s",i),[e.id]))}))}canSetTable(t,e,a){return!0}canDelTable(t,e){return!0}canSetRow(t,e,a,s){return!0}canDelRow(t,e,a){return!0}canSetCell(t,e,a,s,n,r,i){return!0}canDelCell(t,e,a,s){return!0}canSetValue(t,e,a,s,n){return!0}canDelValue(t,e){return!0}},exports.hasStoreInStorage=R,exports.loadStoreFromStorage=b;
|
|
Binary file
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";const e=e=>typeof e,t="",n=
|
|
1
|
+
"use strict";const e=e=>typeof e,t=e(""),n="t",r=(e,t)=>e.startsWith(t),s=Promise,i=e=>null==e,o=(e,t,n)=>i(e)?null==n?void 0:n():t(e),l=(e,t,n)=>e.slice(t,n),a=e=>e.length,c=e=>{return t=function*(){return s.all(e)},new Promise(((e,n)=>{var r=e=>{try{i(t.next(e))}catch(e){n(e)}},s=e=>{try{i(t.throw(e))}catch(e){n(e)}},i=t=>t.done?e(t.value):Promise.resolve(t.value).then(r,s);i((t=t.apply(void 0,null)).next())}));var t},u=(e,t)=>e.map(t),d=(e,...t)=>e.push(...t),h=Object,f=(e=[])=>h.fromEntries(e),y=(e,t)=>u(h.entries(e),(([e,n])=>t(n,e))),g=(e,t,n)=>(((e,t)=>!i(((e,t)=>o(e,(e=>e[t])))(e,t)))(e,t)||(e[t]=n()),e[t]),v=e=>JSON.stringify(e,((e,t)=>t instanceof Map?h.fromEntries([...t]):t)),p=JSON.parse,P=(n,r,s)=>n+r+(e(s)==t?s:v(s)),S=(e,t,n)=>{const s=a(e);return r(t,e)?[t[s],(n?p:String)(l(t,s+1))]:void 0},x=(e,t)=>((e,t)=>null==e?void 0:e.forEach(t))(e,((e,n)=>t(n,e)));var m=(e,t,n)=>new Promise(((r,s)=>{var i=e=>{try{l(n.next(e))}catch(e){s(e)}},o=e=>{try{l(n.throw(e))}catch(e){s(e)}},l=e=>e.done?r(e.value):Promise.resolve(e.value).then(i,o);l((n=n.apply(e,t)).next())}));const w="hasStore",D=f(u(["Origin","Methods","Headers"],(e=>["Access-Control-Allow-"+e,"*"]))),R=(e,...t)=>m(void 0,[e,...t],(function*(e,t=""){return!!(yield e.get(t+w))})),b=(e,...t)=>m(void 0,[e,...t],(function*(e,t=""){const r={},s={};return x(yield e.list(),((e,i)=>o(S(t,e),(([e,t])=>{if(e==n){const[e,n,s]=p("["+t+"]");g(g(r,e,f),n,f)[s]=i}else"v"==e&&(s[t]=i)})))),[r,s]})),T=(e,t,s,o)=>m(void 0,null,(function*(){const l=e.party.storage,u=e.config.storagePrefix,h={[u+w]:1},f=[],g=[];yield c(y(t[0],((t,r)=>m(void 0,null,(function*(){return i(t)?!s&&e.canDelTable(r,o)&&((e,...t)=>e.unshift(...t))(g,C(u,n,r)):e.canSetTable(r,s,o)&&(yield c(y(t,((t,a)=>m(void 0,null,(function*(){return i(t)?!s&&e.canDelRow(r,a,o)&&d(g,C(u,n,r,a)):e.canSetRow(r,a,s,o)&&(yield c(y(t,((t,c)=>m(void 0,null,(function*(){const y=[r,a,c],g=C(u,n,...y);i(t)?!s&&e.canDelCell(...y,o)&&d(f,g):e.canSetCell(...y,t,s,o,yield l.get(g))&&(h[g]=t)}))))))}))))))}))))),yield c(y(t[1],((t,n)=>m(void 0,null,(function*(){const r=u+"v"+n;i(t)?!s&&e.canDelValue(n,o)&&d(f,r):e.canSetValue(n,t,s,o,yield l.get(r))&&(h[r]=t)}))))),0!=a(g)&&x(yield l.list(),(e=>g.every((t=>!r(e,t)||d(f,e)&&0)))),yield l.delete(f),yield l.put(h)})),C=(e,t,...n)=>P(e,t,l(v(n),1,-1)),H=(e,t,n=null)=>m(void 0,null,(function*(){return new Response(n,{status:t,headers:e.config.responseHeaders})}));exports.TinyBasePartyKitServer=class{constructor(e){var t,n,r,s;this.party=e,this.config={},null!=(t=this.config).storePath||(t.storePath="/store"),null!=(n=this.config).messagePrefix||(n.messagePrefix=""),null!=(r=this.config).storagePrefix||(r.storagePrefix=""),null!=(s=this.config).responseHeaders||(s.responseHeaders=D)}onRequest(e){return m(this,null,(function*(){const{party:{storage:t},config:{storePath:n,storagePrefix:r}}=this;if(new URL(e.url).pathname.endsWith(n)){const n=yield R(t,r),s=yield e.text();return"PUT"==e.method?n?H(this,205):(yield T(this,p(s),!0,e),H(this,201)):H(this,200,n?v(yield b(t,r)):"")}return H(this,404)}))}onMessage(e,t){return m(this,null,(function*(){const{party:{storage:n,broadcast:r},config:{messagePrefix:s,storagePrefix:i}}=this;yield o(S(s,e,1),(e=>m(this,[e],(function*([e,o]){"s"==e&&(yield R(n,i))&&(yield T(this,o,!1,t),r(P(s,"s",o),[t.id]))}))))}))}canSetTable(e,t,n){return!0}canDelTable(e,t){return!0}canSetRow(e,t,n,r){return!0}canDelRow(e,t,n){return!0}canSetCell(e,t,n,r,s,i,o){return!0}canDelCell(e,t,n,r){return!0}canSetValue(e,t,n,r,s){return!0}canDelValue(e,t){return!0}},exports.hasStoreInStorage=R,exports.loadStoreFromStorage=b;
|
|
Binary file
|
|
@@ -67,15 +67,12 @@ const RESPONSE_HEADERS = objNew(
|
|
|
67
67
|
'*',
|
|
68
68
|
]),
|
|
69
69
|
);
|
|
70
|
-
const
|
|
71
|
-
await
|
|
72
|
-
|
|
73
|
-
);
|
|
74
|
-
const loadStore = async (that) => {
|
|
70
|
+
const hasStoreInStorage = async (storage, storagePrefix = EMPTY_STRING) =>
|
|
71
|
+
!!(await storage.get(storagePrefix + HAS_STORE));
|
|
72
|
+
const loadStoreFromStorage = async (storage, storagePrefix = EMPTY_STRING) => {
|
|
75
73
|
const tables = {};
|
|
76
74
|
const values = {};
|
|
77
|
-
|
|
78
|
-
mapForEach(await that.party.storage.list(), (key, cellOrValue) =>
|
|
75
|
+
mapForEach(await storage.list(), (key, cellOrValue) =>
|
|
79
76
|
ifNotUndefined(deconstruct(storagePrefix, key), ([type, ids]) => {
|
|
80
77
|
if (type == T) {
|
|
81
78
|
const [tableId, rowId, cellId] = jsonParse('[' + ids + ']');
|
|
@@ -95,9 +92,9 @@ const saveStore = async (
|
|
|
95
92
|
requestOrConnection,
|
|
96
93
|
) => {
|
|
97
94
|
const storage = that.party.storage;
|
|
98
|
-
const
|
|
95
|
+
const storagePrefix = that.config.storagePrefix;
|
|
99
96
|
const keysToSet = {
|
|
100
|
-
[
|
|
97
|
+
[storagePrefix + HAS_STORE]: 1,
|
|
101
98
|
};
|
|
102
99
|
const keysToDel = [];
|
|
103
100
|
const keyPrefixesToDel = [];
|
|
@@ -108,7 +105,7 @@ const saveStore = async (
|
|
|
108
105
|
that.canDelTable(tableId, requestOrConnection) &&
|
|
109
106
|
arrayUnshift(
|
|
110
107
|
keyPrefixesToDel,
|
|
111
|
-
constructStorageKey(
|
|
108
|
+
constructStorageKey(storagePrefix, T, tableId),
|
|
112
109
|
)
|
|
113
110
|
: that.canSetTable(tableId, initialSave, requestOrConnection) &&
|
|
114
111
|
(await promiseAll(
|
|
@@ -118,7 +115,7 @@ const saveStore = async (
|
|
|
118
115
|
that.canDelRow(tableId, rowId, requestOrConnection) &&
|
|
119
116
|
arrayPush(
|
|
120
117
|
keyPrefixesToDel,
|
|
121
|
-
constructStorageKey(
|
|
118
|
+
constructStorageKey(storagePrefix, T, tableId, rowId),
|
|
122
119
|
)
|
|
123
120
|
: that.canSetRow(
|
|
124
121
|
tableId,
|
|
@@ -129,7 +126,7 @@ const saveStore = async (
|
|
|
129
126
|
(await promiseAll(
|
|
130
127
|
objMap(row, async (cell, cellId) => {
|
|
131
128
|
const ids = [tableId, rowId, cellId];
|
|
132
|
-
const key = constructStorageKey(
|
|
129
|
+
const key = constructStorageKey(storagePrefix, T, ...ids);
|
|
133
130
|
isUndefined(cell)
|
|
134
131
|
? !initialSave &&
|
|
135
132
|
that.canDelCell(...ids, requestOrConnection) &&
|
|
@@ -149,7 +146,7 @@ const saveStore = async (
|
|
|
149
146
|
);
|
|
150
147
|
await promiseAll(
|
|
151
148
|
objMap(transactionChanges[1], async (value, valueId) => {
|
|
152
|
-
const key =
|
|
149
|
+
const key = storagePrefix + V + valueId;
|
|
153
150
|
isUndefined(value)
|
|
154
151
|
? !initialSave &&
|
|
155
152
|
that.canDelValue(valueId, requestOrConnection) &&
|
|
@@ -181,17 +178,24 @@ const constructStorageKey = (storagePrefix, type, ...ids) =>
|
|
|
181
178
|
const createResponse = async (that, status, body = null) =>
|
|
182
179
|
new Response(body, {
|
|
183
180
|
status,
|
|
184
|
-
headers: that.config.responseHeaders
|
|
181
|
+
headers: that.config.responseHeaders,
|
|
185
182
|
});
|
|
186
183
|
class TinyBasePartyKitServer {
|
|
187
184
|
constructor(party) {
|
|
188
185
|
this.party = party;
|
|
189
186
|
this.config = {};
|
|
187
|
+
this.config.storePath ??= STORE_PATH;
|
|
188
|
+
this.config.messagePrefix ??= EMPTY_STRING;
|
|
189
|
+
this.config.storagePrefix ??= EMPTY_STRING;
|
|
190
|
+
this.config.responseHeaders ??= RESPONSE_HEADERS;
|
|
190
191
|
}
|
|
191
192
|
async onRequest(request) {
|
|
192
|
-
const
|
|
193
|
+
const {
|
|
194
|
+
party: {storage},
|
|
195
|
+
config: {storePath, storagePrefix},
|
|
196
|
+
} = this;
|
|
193
197
|
if (new URL(request.url).pathname.endsWith(storePath)) {
|
|
194
|
-
const hasExistingStore = await
|
|
198
|
+
const hasExistingStore = await hasStoreInStorage(storage, storagePrefix);
|
|
195
199
|
const text = await request.text();
|
|
196
200
|
if (request.method == PUT) {
|
|
197
201
|
if (hasExistingStore) {
|
|
@@ -203,19 +207,29 @@ class TinyBasePartyKitServer {
|
|
|
203
207
|
return createResponse(
|
|
204
208
|
this,
|
|
205
209
|
200,
|
|
206
|
-
hasExistingStore
|
|
210
|
+
hasExistingStore
|
|
211
|
+
? jsonString(await loadStoreFromStorage(storage, storagePrefix))
|
|
212
|
+
: EMPTY_STRING,
|
|
207
213
|
);
|
|
208
214
|
}
|
|
209
215
|
return createResponse(this, 404);
|
|
210
216
|
}
|
|
211
217
|
async onMessage(message, connection) {
|
|
212
|
-
const
|
|
218
|
+
const {
|
|
219
|
+
party: {storage, broadcast},
|
|
220
|
+
config: {messagePrefix, storagePrefix},
|
|
221
|
+
} = this;
|
|
213
222
|
await ifNotUndefined(
|
|
214
223
|
deconstruct(messagePrefix, message, 1),
|
|
215
224
|
async ([type, payload]) => {
|
|
216
|
-
if (
|
|
225
|
+
if (
|
|
226
|
+
type == SET_CHANGES &&
|
|
227
|
+
(await hasStoreInStorage(storage, storagePrefix))
|
|
228
|
+
) {
|
|
217
229
|
await saveStore(this, payload, false, connection);
|
|
218
|
-
|
|
230
|
+
broadcast(construct(messagePrefix, SET_CHANGES, payload), [
|
|
231
|
+
connection.id,
|
|
232
|
+
]);
|
|
219
233
|
}
|
|
220
234
|
},
|
|
221
235
|
);
|
|
@@ -254,4 +268,4 @@ class TinyBasePartyKitServer {
|
|
|
254
268
|
}
|
|
255
269
|
}
|
|
256
270
|
|
|
257
|
-
export {TinyBasePartyKitServer};
|
|
271
|
+
export {TinyBasePartyKitServer, hasStoreInStorage, loadStoreFromStorage};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
const e=e=>typeof e,t="",n=
|
|
1
|
+
const e=e=>typeof e,t=e(""),n="t",r=(e,t)=>e.startsWith(t),i=Promise,l=e=>null==e,s=(e,t,n)=>l(e)?null==n?void 0:n():t(e),o=(e,t,n)=>e.slice(t,n),a=e=>e.length,c=e=>{return t=function*(){return i.all(e)},new Promise(((e,n)=>{var r=e=>{try{l(t.next(e))}catch(e){n(e)}},i=e=>{try{l(t.throw(e))}catch(e){n(e)}},l=t=>t.done?e(t.value):Promise.resolve(t.value).then(r,i);l((t=t.apply(void 0,null)).next())}));var t},u=(e,t)=>e.map(t),d=(e,...t)=>e.push(...t),h=Object,f=(e=[])=>h.fromEntries(e),y=(e,t)=>u(h.entries(e),(([e,n])=>t(n,e))),g=(e,t,n)=>(((e,t)=>!l(((e,t)=>s(e,(e=>e[t])))(e,t)))(e,t)||(e[t]=n()),e[t]),v=e=>JSON.stringify(e,((e,t)=>t instanceof Map?h.fromEntries([...t]):t)),p=JSON.parse,P=(n,r,i)=>n+r+(e(i)==t?i:v(i)),x=(e,t,n)=>{const i=a(e);return r(t,e)?[t[i],(n?p:String)(o(t,i+1))]:void 0},m=(e,t)=>((e,t)=>null==e?void 0:e.forEach(t))(e,((e,n)=>t(n,e)));var S=(e,t,n)=>new Promise(((r,i)=>{var l=e=>{try{o(n.next(e))}catch(e){i(e)}},s=e=>{try{o(n.throw(e))}catch(e){i(e)}},o=e=>e.done?r(e.value):Promise.resolve(e.value).then(l,s);o((n=n.apply(e,t)).next())}));const w="hasStore",D=f(u(["Origin","Methods","Headers"],(e=>["Access-Control-Allow-"+e,"*"]))),R=(e,...t)=>S(void 0,[e,...t],(function*(e,t=""){return!!(yield e.get(t+w))})),b=(e,...t)=>S(void 0,[e,...t],(function*(e,t=""){const r={},i={};return m(yield e.list(),((e,l)=>s(x(t,e),(([e,t])=>{if(e==n){const[e,n,i]=p("["+t+"]");g(g(r,e,f),n,f)[i]=l}else"v"==e&&(i[t]=l)})))),[r,i]})),C=(e,t,i,s)=>S(void 0,null,(function*(){const o=e.party.storage,u=e.config.storagePrefix,h={[u+w]:1},f=[],g=[];yield c(y(t[0],((t,r)=>S(void 0,null,(function*(){return l(t)?!i&&e.canDelTable(r,s)&&((e,...t)=>e.unshift(...t))(g,T(u,n,r)):e.canSetTable(r,i,s)&&(yield c(y(t,((t,a)=>S(void 0,null,(function*(){return l(t)?!i&&e.canDelRow(r,a,s)&&d(g,T(u,n,r,a)):e.canSetRow(r,a,i,s)&&(yield c(y(t,((t,c)=>S(void 0,null,(function*(){const y=[r,a,c],g=T(u,n,...y);l(t)?!i&&e.canDelCell(...y,s)&&d(f,g):e.canSetCell(...y,t,i,s,yield o.get(g))&&(h[g]=t)}))))))}))))))}))))),yield c(y(t[1],((t,n)=>S(void 0,null,(function*(){const r=u+"v"+n;l(t)?!i&&e.canDelValue(n,s)&&d(f,r):e.canSetValue(n,t,i,s,yield o.get(r))&&(h[r]=t)}))))),0!=a(g)&&m(yield o.list(),(e=>g.every((t=>!r(e,t)||d(f,e)&&0)))),yield o.delete(f),yield o.put(h)})),T=(e,t,...n)=>P(e,t,o(v(n),1,-1)),H=(e,t,n=null)=>S(void 0,null,(function*(){return new Response(n,{status:t,headers:e.config.responseHeaders})}));class O{constructor(e){var t,n,r,i;this.party=e,this.config={},null!=(t=this.config).storePath||(t.storePath="/store"),null!=(n=this.config).messagePrefix||(n.messagePrefix=""),null!=(r=this.config).storagePrefix||(r.storagePrefix=""),null!=(i=this.config).responseHeaders||(i.responseHeaders=D)}onRequest(e){return S(this,null,(function*(){const{party:{storage:t},config:{storePath:n,storagePrefix:r}}=this;if(new URL(e.url).pathname.endsWith(n)){const n=yield R(t,r),i=yield e.text();return"PUT"==e.method?n?H(this,205):(yield C(this,p(i),!0,e),H(this,201)):H(this,200,n?v(yield b(t,r)):"")}return H(this,404)}))}onMessage(e,t){return S(this,null,(function*(){const{party:{storage:n,broadcast:r},config:{messagePrefix:i,storagePrefix:l}}=this;yield s(x(i,e,1),(e=>S(this,[e],(function*([e,s]){"s"==e&&(yield R(n,l))&&(yield C(this,s,!1,t),r(P(i,"s",s),[t.id]))}))))}))}canSetTable(e,t,n){return!0}canDelTable(e,t){return!0}canSetRow(e,t,n,r){return!0}canDelRow(e,t,n){return!0}canSetCell(e,t,n,r,i,l,s){return!0}canDelCell(e,t,n,r){return!0}canSetValue(e,t,n,r,i){return!0}canDelValue(e,t){return!0}}export{O as TinyBasePartyKitServer,R as hasStoreInStorage,b as loadStoreFromStorage};
|
|
Binary file
|
|
@@ -1 +1 @@
|
|
|
1
|
-
const t=t=>typeof t,
|
|
1
|
+
const t=t=>typeof t,e=t(""),a="t",s=(t,e)=>t.startsWith(e),n=Promise,r=t=>null==t,i=(t,e,a)=>r(t)?a?.():e(t),c=(t,e,a)=>t.slice(e,a),o=t=>t.length,l=async t=>n.all(t),h=(t,e)=>t.map(e),g=(t,...e)=>t.push(...e),u=Object,w=(t=[])=>u.fromEntries(t),f=(t,e)=>h(u.entries(t),(([t,a])=>e(a,t))),y=(t,e,a)=>(((t,e)=>!r(((t,e)=>i(t,(t=>t[e])))(t,e)))(t,e)||(t[e]=a()),t[e]),p=t=>JSON.stringify(t,((t,e)=>e instanceof Map?u.fromEntries([...e]):e)),S=JSON.parse,d=(a,s,n)=>a+s+(t(n)==e?n:p(n)),P=(t,e,a)=>{const n=o(t);return s(e,t)?[e[n],(a?S:String)(c(e,n+1))]:void 0},m=(t,e)=>((t,e)=>t?.forEach(e))(t,((t,a)=>e(a,t))),x="hasStore",D=w(h(["Origin","Methods","Headers"],(t=>["Access-Control-Allow-"+t,"*"]))),R=async(t,e="")=>!!await t.get(e+x),b=async(t,e="")=>{const s={},n={};return m(await t.list(),((t,r)=>i(P(e,t),(([t,e])=>{if(t==a){const[t,a,n]=S("["+e+"]");y(y(s,t,w),a,w)[n]=r}else"v"==t&&(n[e]=r)})))),[s,n]},C=async(t,e,n,i)=>{const c=t.party.storage,h=t.config.storagePrefix,u={[h+x]:1},w=[],y=[];await l(f(e[0],(async(e,s)=>r(e)?!n&&t.canDelTable(s,i)&&((t,...e)=>t.unshift(...e))(y,T(h,a,s)):t.canSetTable(s,n,i)&&await l(f(e,(async(e,o)=>r(e)?!n&&t.canDelRow(s,o,i)&&g(y,T(h,a,s,o)):t.canSetRow(s,o,n,i)&&await l(f(e,(async(e,l)=>{const f=[s,o,l],y=T(h,a,...f);r(e)?!n&&t.canDelCell(...f,i)&&g(w,y):t.canSetCell(...f,e,n,i,await c.get(y))&&(u[y]=e)}))))))))),await l(f(e[1],(async(e,a)=>{const s=h+"v"+a;r(e)?!n&&t.canDelValue(a,i)&&g(w,s):t.canSetValue(a,e,n,i,await c.get(s))&&(u[s]=e)}))),0!=o(y)&&m(await c.list(),(t=>y.every((e=>!s(t,e)||g(w,t)&&0)))),await c.delete(w),await c.put(u)},T=(t,e,...a)=>d(t,e,c(p(a),1,-1)),v=async(t,e,a=null)=>new Response(a,{status:e,headers:t.config.responseHeaders});class O{constructor(t){this.party=t,this.config={},this.config.storePath??="/store",this.config.messagePrefix??="",this.config.storagePrefix??="",this.config.responseHeaders??=D}async onRequest(t){const{party:{storage:e},config:{storePath:a,storagePrefix:s}}=this;if(new URL(t.url).pathname.endsWith(a)){const a=await R(e,s),n=await t.text();return"PUT"==t.method?a?v(this,205):(await C(this,S(n),!0,t),v(this,201)):v(this,200,a?p(await b(e,s)):"")}return v(this,404)}async onMessage(t,e){const{party:{storage:a,broadcast:s},config:{messagePrefix:n,storagePrefix:r}}=this;await i(P(n,t,1),(async([t,i])=>{"s"==t&&await R(a,r)&&(await C(this,i,!1,e),s(d(n,"s",i),[e.id]))}))}canSetTable(t,e,a){return!0}canDelTable(t,e){return!0}canSetRow(t,e,a,s){return!0}canDelRow(t,e,a){return!0}canSetCell(t,e,a,s,n,r,i){return!0}canDelCell(t,e,a,s){return!0}canSetValue(t,e,a,s,n){return!0}canDelValue(t,e){return!0}}export{O as TinyBasePartyKitServer,R as hasStoreInStorage,b as loadStoreFromStorage};
|
|
Binary file
|
|
@@ -18,8 +18,15 @@
|
|
|
18
18
|
* @since 4.3.0
|
|
19
19
|
*/
|
|
20
20
|
|
|
21
|
-
import {
|
|
22
|
-
|
|
21
|
+
import {
|
|
22
|
+
Cell,
|
|
23
|
+
CellOrUndefined,
|
|
24
|
+
Tables,
|
|
25
|
+
Value,
|
|
26
|
+
ValueOrUndefined,
|
|
27
|
+
Values,
|
|
28
|
+
} from '../store';
|
|
29
|
+
import {Connection, Party, Request, Server, Storage} from 'partykit/server';
|
|
23
30
|
import {Id} from '../common';
|
|
24
31
|
|
|
25
32
|
/**
|
|
@@ -517,3 +524,52 @@ export class TinyBasePartyKitServer implements Server {
|
|
|
517
524
|
*/
|
|
518
525
|
canDelValue(valueId: Id, connection: Connection): boolean;
|
|
519
526
|
}
|
|
527
|
+
|
|
528
|
+
/**
|
|
529
|
+
* The hasStoreInStorage function returns a boolean indicating whether durable
|
|
530
|
+
* PartyKit storage contains a serialized Store.
|
|
531
|
+
*
|
|
532
|
+
* This is intended for specialist applications that require the ability to
|
|
533
|
+
* inspect or load a TinyBase Store from a server's storage outside of the
|
|
534
|
+
* normal context of a TinyBasePartyKitServer.
|
|
535
|
+
*
|
|
536
|
+
* The function is asynchronous, so you should use the `await` keyword or handle
|
|
537
|
+
* the result as a promise.
|
|
538
|
+
* @param storage A reference to the storage object, as would normally be
|
|
539
|
+
* accessible from the `TinyBasePartyKitServer.party` object.
|
|
540
|
+
* @param storagePrefix An optional prefix used before all the keys in the
|
|
541
|
+
* server's durable storage, to match the equivalent property in the server's
|
|
542
|
+
* TinyBasePartyKitServerConfig.
|
|
543
|
+
* @returns A promised boolean indicating whether a Store is present in the
|
|
544
|
+
* storage.
|
|
545
|
+
* @category Storage
|
|
546
|
+
* @since v4.4.1
|
|
547
|
+
*/
|
|
548
|
+
export function hasStoreInStorage(
|
|
549
|
+
storage: Storage,
|
|
550
|
+
storagePrefix?: string,
|
|
551
|
+
): Promise<boolean>;
|
|
552
|
+
|
|
553
|
+
/**
|
|
554
|
+
* The loadStoreFromStorage function returns the content of a Store from durable
|
|
555
|
+
* PartyKit storage.
|
|
556
|
+
*
|
|
557
|
+
* This is intended for specialist applications that require the ability to
|
|
558
|
+
* inspect or load a TinyBase Store from a server's storage outside of the
|
|
559
|
+
* normal context of a TinyBasePartyKitServer.
|
|
560
|
+
*
|
|
561
|
+
* The function is asynchronous, so you should use the `await` keyword or handle
|
|
562
|
+
* the result as a promise.
|
|
563
|
+
* @param storage A reference to the storage object, as would normally be
|
|
564
|
+
* accessible from the `TinyBasePartyKitServer.party` object.
|
|
565
|
+
* @param storagePrefix An optional prefix used before all the keys in the
|
|
566
|
+
* server's durable storage, to match the equivalent property in the server's
|
|
567
|
+
* TinyBasePartyKitServerConfig.
|
|
568
|
+
* @returns A promised array of a Tables object and a Values object.
|
|
569
|
+
* @category Storage
|
|
570
|
+
* @since v4.4.1
|
|
571
|
+
*/
|
|
572
|
+
export function loadStoreFromStorage(
|
|
573
|
+
storage: Storage,
|
|
574
|
+
storagePrefix?: string,
|
|
575
|
+
): Promise<[Tables, Values]>;
|
|
@@ -55,8 +55,13 @@ export interface RemotePersister extends Persister {
|
|
|
55
55
|
* the `POST` method (to send the Store JSON to save) respectively.
|
|
56
56
|
*
|
|
57
57
|
* For when you choose to enable automatic loading for the Persister (with the
|
|
58
|
-
* startAutoLoad method), it will poll the loadUrl for changes
|
|
58
|
+
* startAutoLoad method), it will poll the loadUrl for changes, using the
|
|
59
|
+
* `ETag` HTTP header to identify if things have changed. The
|
|
59
60
|
* `autoLoadIntervalSeconds` method is used to indicate how often to do this.
|
|
61
|
+
*
|
|
62
|
+
* If you are implementing the server portion of this functionality yourself,
|
|
63
|
+
* remember to ensure that the `ETag` header changes every time the server's
|
|
64
|
+
* Store content does - otherwise changes will not be detected by the client.
|
|
60
65
|
* @param store The Store to persist.
|
|
61
66
|
* @param loadUrl The endpoint that supports a `GET` method to load JSON.
|
|
62
67
|
* @param saveUrl The endpoint that supports a `POST` method to save JSON.
|
|
@@ -23,8 +23,11 @@ import {
|
|
|
23
23
|
CellOrUndefined,
|
|
24
24
|
NoTablesSchema,
|
|
25
25
|
NoValuesSchema,
|
|
26
|
+
OptionalSchemas,
|
|
27
|
+
Tables,
|
|
26
28
|
Value,
|
|
27
29
|
ValueOrUndefined,
|
|
30
|
+
Values,
|
|
28
31
|
} from '../store';
|
|
29
32
|
import {Connection, Party, Request, Server} from 'partykit/server';
|
|
30
33
|
import {Id} from '../common';
|
|
@@ -550,3 +553,61 @@ export class TinyBasePartyKitServer implements Server {
|
|
|
550
553
|
*/
|
|
551
554
|
canDelValue(valueId: Id, connection: Connection): boolean;
|
|
552
555
|
}
|
|
556
|
+
|
|
557
|
+
/**
|
|
558
|
+
* The hasStoreInStorage function returns a boolean indicating whether durable
|
|
559
|
+
* PartyKit storage contains a serialized Store.
|
|
560
|
+
*
|
|
561
|
+
* This is intended for specialist applications that require the ability to
|
|
562
|
+
* inspect or load a TinyBase Store from a server's storage outside of the
|
|
563
|
+
* normal context of a TinyBasePartyKitServer.
|
|
564
|
+
*
|
|
565
|
+
* The function is asynchronous, so you should use the `await` keyword or handle
|
|
566
|
+
* the result as a promise.
|
|
567
|
+
* @param storage A reference to the storage object, as would normally be
|
|
568
|
+
* accessible from the `TinyBasePartyKitServer.party` object.
|
|
569
|
+
* @param storagePrefix An optional prefix used before all the keys in the
|
|
570
|
+
* server's durable storage, to match the equivalent property in the server's
|
|
571
|
+
* TinyBasePartyKitServerConfig.
|
|
572
|
+
* @returns A promised boolean indicating whether a Store is present in the
|
|
573
|
+
* storage.
|
|
574
|
+
* @category Storage
|
|
575
|
+
* @since v4.4.1
|
|
576
|
+
*/
|
|
577
|
+
export function hasStoreInStorage(
|
|
578
|
+
storage: Storage,
|
|
579
|
+
storagePrefix?: string,
|
|
580
|
+
): Promise<boolean>;
|
|
581
|
+
|
|
582
|
+
/**
|
|
583
|
+
* The loadStoreFromStorage function returns the content of a Store from durable
|
|
584
|
+
* PartyKit storage.
|
|
585
|
+
*
|
|
586
|
+
* This has schema-based typing. The following is a simplified representation:
|
|
587
|
+
*
|
|
588
|
+
* ```ts override
|
|
589
|
+
* loadStoreFromStorage(
|
|
590
|
+
* storage: Storage,
|
|
591
|
+
* storagePrefix?: string,
|
|
592
|
+
* ): Promise<[Tables, Values]>;
|
|
593
|
+
* ```
|
|
594
|
+
*
|
|
595
|
+
* This is intended for specialist applications that require the ability to
|
|
596
|
+
* inspect or load a TinyBase Store from a server's storage outside of the
|
|
597
|
+
* normal context of a TinyBasePartyKitServer.
|
|
598
|
+
*
|
|
599
|
+
* The function is asynchronous, so you should use the `await` keyword or handle
|
|
600
|
+
* the result as a promise.
|
|
601
|
+
* @param storage A reference to the storage object, as would normally be
|
|
602
|
+
* accessible from the `TinyBasePartyKitServer.party` object.
|
|
603
|
+
* @param storagePrefix An optional prefix used before all the keys in the
|
|
604
|
+
* server's durable storage, to match the equivalent property in the server's
|
|
605
|
+
* TinyBasePartyKitServerConfig.
|
|
606
|
+
* @returns A promised array of a Tables object and a Values object.
|
|
607
|
+
* @category Storage
|
|
608
|
+
* @since v4.4.1
|
|
609
|
+
*/
|
|
610
|
+
export function loadStoreFromStorage<Schemas extends OptionalSchemas>(
|
|
611
|
+
storage: Storage,
|
|
612
|
+
storagePrefix?: string,
|
|
613
|
+
): Promise<[Tables<Schemas[0]>, Values<Schemas[1]>]>;
|
|
@@ -68,8 +68,13 @@ export interface RemotePersister<Schemas extends OptionalSchemas>
|
|
|
68
68
|
* the `POST` method (to send the Store JSON to save) respectively.
|
|
69
69
|
*
|
|
70
70
|
* For when you choose to enable automatic loading for the Persister (with the
|
|
71
|
-
* startAutoLoad method), it will poll the loadUrl for changes
|
|
71
|
+
* startAutoLoad method), it will poll the loadUrl for changes, using the
|
|
72
|
+
* `ETag` HTTP header to identify if things have changed. The
|
|
72
73
|
* `autoLoadIntervalSeconds` method is used to indicate how often to do this.
|
|
74
|
+
*
|
|
75
|
+
* If you are implementing the server portion of this functionality yourself,
|
|
76
|
+
* remember to ensure that the `ETag` header changes every time the server's
|
|
77
|
+
* Store content does - otherwise changes will not be detected by the client.
|
|
73
78
|
* @param store The Store to persist.
|
|
74
79
|
* @param loadUrl The endpoint that supports a `GET` method to load JSON.
|
|
75
80
|
* @param saveUrl The endpoint that supports a `POST` method to save JSON.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
var t
|
|
1
|
+
var e,t;e=this,t=function(e){"use strict";const t=e=>typeof e,a=t(""),s="t",n=(e,t)=>e.startsWith(t),r=Promise,i=e=>null==e,o=(e,t,a)=>i(e)?a?.():t(e),c=(e,t,a)=>e.slice(t,a),l=e=>e.length,f=async e=>r.all(e),h=(e,t)=>e.map(t),u=(e,...t)=>e.push(...t),g=Object,y=(e=[])=>g.fromEntries(e),w=(e,t)=>h(g.entries(e),(([e,a])=>t(a,e))),d=(e,t,a)=>(((e,t)=>!i(((e,t)=>o(e,(e=>e[t])))(e,t)))(e,t)||(e[t]=a()),e[t]),p=e=>JSON.stringify(e,((e,t)=>t instanceof Map?g.fromEntries([...t]):t)),S=JSON.parse,P=(e,s,n)=>e+s+(t(n)==a?n:p(n)),m=(e,t,a)=>{const s=l(e);return n(t,e)?[t[s],(a?S:String)(c(t,s+1))]:void 0},x=(e,t)=>((e,t)=>e?.forEach(t))(e,((e,a)=>t(a,e))),b="hasStore",T=y(h(["Origin","Methods","Headers"],(e=>["Access-Control-Allow-"+e,"*"]))),D=async(e,t="")=>!!await e.get(t+b),v=async(e,t="")=>{const a={},n={};return x(await e.list(),((e,r)=>o(m(t,e),(([e,t])=>{if(e==s){const[e,s,n]=S("["+t+"]");d(d(a,e,y),s,y)[n]=r}else"v"==e&&(n[t]=r)})))),[a,n]},R=async(e,t,a,r)=>{const o=e.party.storage,c=e.config.storagePrefix,h={[c+b]:1},g=[],y=[];await f(w(t[0],(async(t,n)=>i(t)?!a&&e.canDelTable(n,r)&&((e,...t)=>e.unshift(...t))(y,C(c,s,n)):e.canSetTable(n,a,r)&&await f(w(t,(async(t,l)=>i(t)?!a&&e.canDelRow(n,l,r)&&u(y,C(c,s,n,l)):e.canSetRow(n,l,a,r)&&await f(w(t,(async(t,f)=>{const y=[n,l,f],w=C(c,s,...y);i(t)?!a&&e.canDelCell(...y,r)&&u(g,w):e.canSetCell(...y,t,a,r,await o.get(w))&&(h[w]=t)}))))))))),await f(w(t[1],(async(t,s)=>{const n=c+"v"+s;i(t)?!a&&e.canDelValue(s,r)&&u(g,n):e.canSetValue(s,t,a,r,await o.get(n))&&(h[n]=t)}))),0!=l(y)&&x(await o.list(),(e=>y.every((t=>!n(e,t)||u(g,e)&&0)))),await o.delete(g),await o.put(h)},C=(e,t,...a)=>P(e,t,c(p(a),1,-1)),O=async(e,t,a=null)=>new Response(a,{status:t,headers:e.config.responseHeaders});e.TinyBasePartyKitServer=class{constructor(e){this.party=e,this.config={},this.config.storePath??="/store",this.config.messagePrefix??="",this.config.storagePrefix??="",this.config.responseHeaders??=T}async onRequest(e){const{party:{storage:t},config:{storePath:a,storagePrefix:s}}=this;if(new URL(e.url).pathname.endsWith(a)){const a=await D(t,s),n=await e.text();return"PUT"==e.method?a?O(this,205):(await R(this,S(n),!0,e),O(this,201)):O(this,200,a?p(await v(t,s)):"")}return O(this,404)}async onMessage(e,t){const{party:{storage:a,broadcast:s},config:{messagePrefix:n,storagePrefix:r}}=this;await o(m(n,e,1),(async([e,i])=>{"s"==e&&await D(a,r)&&(await R(this,i,!1,t),s(P(n,"s",i),[t.id]))}))}canSetTable(e,t,a){return!0}canDelTable(e,t){return!0}canSetRow(e,t,a,s){return!0}canDelRow(e,t,a){return!0}canSetCell(e,t,a,s,n,r,i){return!0}canDelCell(e,t,a,s){return!0}canSetValue(e,t,a,s,n){return!0}canDelValue(e,t){return!0}},e.hasStoreInStorage=D,e.loadStoreFromStorage=v},"object"==typeof exports&&"undefined"!=typeof module?t(exports):"function"==typeof define&&define.amd?define(["exports"],t):t((e="undefined"!=typeof globalThis?globalThis:e||self).TinyBasePersisterPartyKitServer={});
|
|
Binary file
|
|
@@ -1 +1 @@
|
|
|
1
|
-
var e,t;e=this,t=function(e){"use strict";const t=e=>typeof e,n="",r=
|
|
1
|
+
var e,t;e=this,t=function(e){"use strict";const t=e=>typeof e,n=t(""),r="t",i=(e,t)=>e.startsWith(t),o=Promise,s=e=>null==e,l=(e,t,n)=>s(e)?null==n?void 0:n():t(e),a=(e,t,n)=>e.slice(t,n),c=e=>e.length,u=e=>{return t=function*(){return o.all(e)},new Promise(((e,n)=>{var r=e=>{try{o(t.next(e))}catch(e){n(e)}},i=e=>{try{o(t.throw(e))}catch(e){n(e)}},o=t=>t.done?e(t.value):Promise.resolve(t.value).then(r,i);o((t=t.apply(void 0,null)).next())}));var t},d=(e,t)=>e.map(t),f=(e,...t)=>e.push(...t),h=Object,y=(e=[])=>h.fromEntries(e),g=(e,t)=>d(h.entries(e),(([e,n])=>t(n,e))),v=(e,t,n)=>(((e,t)=>!s(((e,t)=>l(e,(e=>e[t])))(e,t)))(e,t)||(e[t]=n()),e[t]),p=e=>JSON.stringify(e,((e,t)=>t instanceof Map?h.fromEntries([...t]):t)),P=JSON.parse,S=(e,r,i)=>e+r+(t(i)==n?i:p(i)),m=(e,t,n)=>{const r=c(e);return i(t,e)?[t[r],(n?P:String)(a(t,r+1))]:void 0},x=(e,t)=>((e,t)=>null==e?void 0:e.forEach(t))(e,((e,n)=>t(n,e)));var w=(e,t,n)=>new Promise(((r,i)=>{var o=e=>{try{l(n.next(e))}catch(e){i(e)}},s=e=>{try{l(n.throw(e))}catch(e){i(e)}},l=e=>e.done?r(e.value):Promise.resolve(e.value).then(o,s);l((n=n.apply(e,t)).next())}));const b="hasStore",T=y(d(["Origin","Methods","Headers"],(e=>["Access-Control-Allow-"+e,"*"]))),D=(e,...t)=>w(void 0,[e,...t],(function*(e,t=""){return!!(yield e.get(t+b))})),R=(e,...t)=>w(void 0,[e,...t],(function*(e,t=""){const n={},i={};return x(yield e.list(),((e,o)=>l(m(t,e),(([e,t])=>{if(e==r){const[e,r,i]=P("["+t+"]");v(v(n,e,y),r,y)[i]=o}else"v"==e&&(i[t]=o)})))),[n,i]})),C=(e,t,n,o)=>w(void 0,null,(function*(){const l=e.party.storage,a=e.config.storagePrefix,d={[a+b]:1},h=[],y=[];yield u(g(t[0],((t,i)=>w(void 0,null,(function*(){return s(t)?!n&&e.canDelTable(i,o)&&((e,...t)=>e.unshift(...t))(y,H(a,r,i)):e.canSetTable(i,n,o)&&(yield u(g(t,((t,c)=>w(void 0,null,(function*(){return s(t)?!n&&e.canDelRow(i,c,o)&&f(y,H(a,r,i,c)):e.canSetRow(i,c,n,o)&&(yield u(g(t,((t,u)=>w(void 0,null,(function*(){const y=[i,c,u],g=H(a,r,...y);s(t)?!n&&e.canDelCell(...y,o)&&f(h,g):e.canSetCell(...y,t,n,o,yield l.get(g))&&(d[g]=t)}))))))}))))))}))))),yield u(g(t[1],((t,r)=>w(void 0,null,(function*(){const i=a+"v"+r;s(t)?!n&&e.canDelValue(r,o)&&f(h,i):e.canSetValue(r,t,n,o,yield l.get(i))&&(d[i]=t)}))))),0!=c(y)&&x(yield l.list(),(e=>y.every((t=>!i(e,t)||f(h,e)&&0)))),yield l.delete(h),yield l.put(d)})),H=(e,t,...n)=>S(e,t,a(p(n),1,-1)),O=(e,t,n=null)=>w(void 0,null,(function*(){return new Response(n,{status:t,headers:e.config.responseHeaders})}));e.TinyBasePartyKitServer=class{constructor(e){var t,n,r,i;this.party=e,this.config={},null!=(t=this.config).storePath||(t.storePath="/store"),null!=(n=this.config).messagePrefix||(n.messagePrefix=""),null!=(r=this.config).storagePrefix||(r.storagePrefix=""),null!=(i=this.config).responseHeaders||(i.responseHeaders=T)}onRequest(e){return w(this,null,(function*(){const{party:{storage:t},config:{storePath:n,storagePrefix:r}}=this;if(new URL(e.url).pathname.endsWith(n)){const n=yield D(t,r),i=yield e.text();return"PUT"==e.method?n?O(this,205):(yield C(this,P(i),!0,e),O(this,201)):O(this,200,n?p(yield R(t,r)):"")}return O(this,404)}))}onMessage(e,t){return w(this,null,(function*(){const{party:{storage:n,broadcast:r},config:{messagePrefix:i,storagePrefix:o}}=this;yield l(m(i,e,1),(e=>w(this,[e],(function*([e,s]){"s"==e&&(yield D(n,o))&&(yield C(this,s,!1,t),r(S(i,"s",s),[t.id]))}))))}))}canSetTable(e,t,n){return!0}canDelTable(e,t){return!0}canSetRow(e,t,n,r){return!0}canDelRow(e,t,n){return!0}canSetCell(e,t,n,r,i,o,s){return!0}canDelCell(e,t,n,r){return!0}canSetValue(e,t,n,r,i){return!0}canDelValue(e,t){return!0}},e.hasStoreInStorage=D,e.loadStoreFromStorage=R},"object"==typeof exports&&"undefined"!=typeof module?t(exports):"function"==typeof define&&define.amd?define(["exports"],t):t((e="undefined"!=typeof globalThis?globalThis:e||self).TinyBasePersisterPartyKitServer={});
|
|
Binary file
|
package/package.json
CHANGED
package/readme.md
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
<section id="hero"><h2 id="the-reactive-data-store-for-local-first-apps">The <em>reactive</em> data store for <span>local-first apps</span>.</h2><p id="copy">Build blisteringly fast web apps that work both online and offline. Manage your state locally, synchronize it to the cloud when you need to, or even make it collaborative. But, most importantly... have fun building stuff again!</p></section><p><a href="https://tinybase.org/guides/releases/#v4-4"><em>NEW!</em> v4.4 release</a> <span id="one-with">"The One With More Listeners"</span></p><p><a class="start" href="https://tinybase.org/guides/the-basics/getting-started/">Get started</a></p><p><a href="https://tinybase.org/demos/">Try the demos</a></p><p><a href="https://tinybase.org/api/store/interfaces/store/store/">Read the docs</a></p><hr><ul><li>Manage <a href="#start-with-a-simple-key-value-store">key-value data</a>, <a href="#level-up-to-use-tabular-data">tabular data</a> - or both - with optional <a href="#apply-schemas-to-tables-values">schematization</a> to model your app's data structures.</li><li><a href="#register-granular-listeners">Flexibly reactive</a> to reconciled updates, so you only spend rendering cycles on things that change.</li><li><a href="#build-complex-queries-with-tinyql">Powerful query engine</a> to select, join, filter, group, sort and paginate data - reactively - and without SQL.</li><li>Built-in <a href="#create-indexes-for-fast-lookups">indexing</a>, <a href="#define-metrics-and-aggregations">metric aggregation</a>, <a href="#model-table-relationships">tabular relationships</a> - and even an <a href="#set-checkpoints-for-an-undo-stack">undo stack</a> for your app state.</li><li>Create <a href="#type-definitions-orm-like-apis">type definitions & ORM-like APIs</a>, from schema or inference. <a href="#an-inspector-for-your-data">Inspect your data</a> (<em>new!</em>) directly in the browser.</li><li>Easily <a href="#persist-to-storage-sqlite-crdts">sync your data</a> to browser <a href="https://tinybase.org/api/persister-browser">storage</a>, <a href="https://tinybase.org/api/persister-indexed-db/">IndexedDB</a>, <a href="https://tinybase.org/guides/schemas-and-persistence/database-persistence/">SQLite</a>, <a href="https://tinybase.org/guides/schemas-and-persistence/synchronizing-data/">CRDTs</a>, and (<em>new!</em>) <a href="https://tinybase.org/api/persister-partykit-client/">PartyKit</a>.</li><li>Optional <a href="#call-hooks-to-bind-to-data">bindings to React</a> and (<em>new!</em>) <a href="#pre-built-reactive-components">pre-built components</a> that let you easily build fully reactive user interfaces.</li><li>Tiny by name, tiny by nature: <a href="#did-we-say-tiny">5.0kB - 9.4kB</a>, zero dependencies. <a href="#well-tested-and-documented">100% tested</a>, <a href="https://tinybase.org/guides/the-basics/getting-started/">fully documented</a>, and of course, <a href="https://github.com/tinyplex/tinybase">open source</a>!</li></ul><hr><section id="friends"><h2 id="tinybase-works-great-on-its-own-but-also-plays-well-with-friends">Tinybase works great on its own, but also plays well with friends!</h2><div><a href="https://tinybase.org/guides/building-uis/getting-started-with-ui-react"><img width="48" src="https://tinybase.org/react.svg"> React</a></div><div><a href="https://tinybase.org/api/persister-partykit-client"><img width="48" src="https://tinybase.org/partykit.svg"> PartyKit</a></div><div><a href="https://tinybase.org/guides/schemas-and-persistence/database-persistence"><img width="48" src="https://tinybase.org/sqlite.svg"> SQLite</a></div><div><a href="https://tinybase.org/api/persister-indexed-db/functions/creation/createindexeddbpersister"><img width="48" src="https://tinybase.org/indexeddb.svg"> IndexedDB</a></div><div><a href="https://tinybase.org/api/persister-yjs/functions/creation/createyjspersister"><img width="48" src="https://tinybase.org/yjs.svg"> YJS</a></div><div><a href="https://tinybase.org/api/persister-cr-sqlite-wasm"><img width="48" src="https://tinybase.org/crsqlite.png"> CR-SQLite</a></div><div><a href="https://tinybase.org/api/persister-automerge"><img width="48" src="https://tinybase.org/automerge.svg"> Automerge</a></div></section><hr><section id="follow"><a href="https://github.com/tinyplex/tinybase" target="_blank"><img src="https://img.shields.io/github/stars/tinyplex/tinybase?style=for-the-badge&logo=GitHub&logoColor=%23fff&label=GitHub&labelColor=%23d81b60&color=%23333"> </a><a href="https://discord.com/invite/mGz3mevwP8" target="_blank"><img src="https://img.shields.io/discord/1027918215323590676?style=for-the-badge&logo=discord&logoColor=%23fff&label=Discord&labelColor=%233131e8&color=%23333"> </a><a href="https://twitter.com/tinybasejs" target="_blank"><img src="https://img.shields.io/twitter/follow/tinybasejs?style=for-the-badge&logo=x&logoColor=%23fff&label=Twitter&labelColor=%23333&color=%23333"></a><br><a href="https://github.com/tinyplex/tinybase/discussions" target="_blank"><img src="https://img.shields.io/github/discussions/tinyplex/tinybase?style=for-the-badge&logo=GitHub&logoColor=%23fff&label=Ideas&labelColor=%23d81b60&color=%23333"> </a><a href="https://github.com/tinyplex/tinybase/issues" target="_blank"><img src="https://img.shields.io/github/issues/tinyplex/tinybase?style=for-the-badge&logo=GitHub&logoColor=%23fff&label=Issues&labelColor=%23d81b60&color=%23333"> </a><a href="#well-tested-and-documented"><img src="https://img.shields.io/badge/Tests-100%25-green?style=for-the-badge&logo=jest&logoColor=%23fff&color=%23333&labelColor=%2387c305"> </a><a href="https://www.npmjs.com/package/tinybase/v/4.4.
|
|
1
|
+
<section id="hero"><h2 id="the-reactive-data-store-for-local-first-apps">The <em>reactive</em> data store for <span>local-first apps</span>.</h2><p id="copy">Build blisteringly fast web apps that work both online and offline. Manage your state locally, synchronize it to the cloud when you need to, or even make it collaborative. But, most importantly... have fun building stuff again!</p></section><p><a href="https://tinybase.org/guides/releases/#v4-4"><em>NEW!</em> v4.4 release</a> <span id="one-with">"The One With More Listeners"</span></p><p><a class="start" href="https://tinybase.org/guides/the-basics/getting-started/">Get started</a></p><p><a href="https://tinybase.org/demos/">Try the demos</a></p><p><a href="https://tinybase.org/api/store/interfaces/store/store/">Read the docs</a></p><hr><ul><li>Manage <a href="#start-with-a-simple-key-value-store">key-value data</a>, <a href="#level-up-to-use-tabular-data">tabular data</a> - or both - with optional <a href="#apply-schemas-to-tables-values">schematization</a> to model your app's data structures.</li><li><a href="#register-granular-listeners">Flexibly reactive</a> to reconciled updates, so you only spend rendering cycles on things that change.</li><li><a href="#build-complex-queries-with-tinyql">Powerful query engine</a> to select, join, filter, group, sort and paginate data - reactively - and without SQL.</li><li>Built-in <a href="#create-indexes-for-fast-lookups">indexing</a>, <a href="#define-metrics-and-aggregations">metric aggregation</a>, <a href="#model-table-relationships">tabular relationships</a> - and even an <a href="#set-checkpoints-for-an-undo-stack">undo stack</a> for your app state.</li><li>Create <a href="#type-definitions-orm-like-apis">type definitions & ORM-like APIs</a>, from schema or inference. <a href="#an-inspector-for-your-data">Inspect your data</a> (<em>new!</em>) directly in the browser.</li><li>Easily <a href="#persist-to-storage-sqlite-crdts">sync your data</a> to browser <a href="https://tinybase.org/api/persister-browser">storage</a>, <a href="https://tinybase.org/api/persister-indexed-db/">IndexedDB</a>, <a href="https://tinybase.org/guides/schemas-and-persistence/database-persistence/">SQLite</a>, <a href="https://tinybase.org/guides/schemas-and-persistence/synchronizing-data/">CRDTs</a>, and (<em>new!</em>) <a href="https://tinybase.org/api/persister-partykit-client/">PartyKit</a>.</li><li>Optional <a href="#call-hooks-to-bind-to-data">bindings to React</a> and (<em>new!</em>) <a href="#pre-built-reactive-components">pre-built components</a> that let you easily build fully reactive user interfaces.</li><li>Tiny by name, tiny by nature: <a href="#did-we-say-tiny">5.0kB - 9.4kB</a>, zero dependencies. <a href="#well-tested-and-documented">100% tested</a>, <a href="https://tinybase.org/guides/the-basics/getting-started/">fully documented</a>, and of course, <a href="https://github.com/tinyplex/tinybase">open source</a>!</li></ul><hr><section id="friends"><h2 id="tinybase-works-great-on-its-own-but-also-plays-well-with-friends">Tinybase works great on its own, but also plays well with friends!</h2><div><a href="https://tinybase.org/guides/building-uis/getting-started-with-ui-react"><img width="48" src="https://tinybase.org/react.svg"> React</a></div><div><a href="https://tinybase.org/api/persister-partykit-client"><img width="48" src="https://tinybase.org/partykit.svg"> PartyKit</a></div><div><a href="https://tinybase.org/guides/schemas-and-persistence/database-persistence"><img width="48" src="https://tinybase.org/sqlite.svg"> SQLite</a></div><div><a href="https://tinybase.org/api/persister-indexed-db/functions/creation/createindexeddbpersister"><img width="48" src="https://tinybase.org/indexeddb.svg"> IndexedDB</a></div><div><a href="https://tinybase.org/api/persister-yjs/functions/creation/createyjspersister"><img width="48" src="https://tinybase.org/yjs.svg"> YJS</a></div><div><a href="https://tinybase.org/api/persister-cr-sqlite-wasm"><img width="48" src="https://tinybase.org/crsqlite.png"> CR-SQLite</a></div><div><a href="https://tinybase.org/api/persister-automerge"><img width="48" src="https://tinybase.org/automerge.svg"> Automerge</a></div></section><hr><section id="follow"><a href="https://github.com/tinyplex/tinybase" target="_blank"><img src="https://img.shields.io/github/stars/tinyplex/tinybase?style=for-the-badge&logo=GitHub&logoColor=%23fff&label=GitHub&labelColor=%23d81b60&color=%23333"> </a><a href="https://discord.com/invite/mGz3mevwP8" target="_blank"><img src="https://img.shields.io/discord/1027918215323590676?style=for-the-badge&logo=discord&logoColor=%23fff&label=Discord&labelColor=%233131e8&color=%23333"> </a><a href="https://twitter.com/tinybasejs" target="_blank"><img src="https://img.shields.io/twitter/follow/tinybasejs?style=for-the-badge&logo=x&logoColor=%23fff&label=Twitter&labelColor=%23333&color=%23333"></a><br><a href="https://github.com/tinyplex/tinybase/discussions" target="_blank"><img src="https://img.shields.io/github/discussions/tinyplex/tinybase?style=for-the-badge&logo=GitHub&logoColor=%23fff&label=Ideas&labelColor=%23d81b60&color=%23333"> </a><a href="https://github.com/tinyplex/tinybase/issues" target="_blank"><img src="https://img.shields.io/github/issues/tinyplex/tinybase?style=for-the-badge&logo=GitHub&logoColor=%23fff&label=Issues&labelColor=%23d81b60&color=%23333"> </a><a href="#well-tested-and-documented"><img src="https://img.shields.io/badge/Tests-100%25-green?style=for-the-badge&logo=jest&logoColor=%23fff&color=%23333&labelColor=%2387c305"> </a><a href="https://www.npmjs.com/package/tinybase/v/4.4.1" target="_blank"><img src="https://img.shields.io/npm/v/tinybase?style=for-the-badge&logo=npm&logoColor=%23fff&labelColor=%23bd0005&color=%23333"></a></section><hr><section><h2 id="start-with-a-simple-key-value-store">Start with a simple key-value store.</h2><p>Creating a <a href="https://tinybase.org/api/store/interfaces/store/store/"><code>Store</code></a> requires just a simple call to the <a href="https://tinybase.org/api/store/functions/creation/createstore/"><code>createStore</code></a> function. Once you have one, you can easily set <a href="https://tinybase.org/api/store/type-aliases/store/values/"><code>Values</code></a> in it by unique <a href="https://tinybase.org/api/common/type-aliases/identity/id/"><code>Id</code></a>. And of course you can easily get them back out again.</p><p>Read more about using keyed value data in <a href="https://tinybase.org/guides/the-basics/">The Basics</a> guide.</p></section>
|
|
2
2
|
|
|
3
3
|
```js
|
|
4
4
|
const store = createStore()
|