@graffiti-garden/api 0.2.4 → 0.2.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{index.cjs.js → index.cjs} +1 -1
- package/dist/{index.js → index.mjs} +1 -1
- package/dist/{tests.js → tests.mjs} +1 -1
- package/package.json +8 -8
- /package/dist/{index.cjs.js.map → index.cjs.map} +0 -0
- /package/dist/{index.js.map → index.mjs.map} +0 -0
- /package/dist/{tests.js.map → tests.mjs.map} +0 -0
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
"use strict";var i=Object.defineProperty;var G=Object.getOwnPropertyDescriptor;var O=Object.getOwnPropertyNames;var l=Object.prototype.hasOwnProperty;var u=(e,t)=>{for(var s in t)i(e,s,{get:t[s],enumerable:!0})},x=(e,t,s,b)=>{if(t&&typeof t=="object"||typeof t=="function")for(let r of O(t))!l.call(e,r)&&r!==s&&i(e,r,{get:()=>t[r],enumerable:!(b=G(t,r))||b.enumerable});return e};var j=e=>x(i({},"__esModule",{value:!0}),e);var y={};u(y,{Graffiti:()=>a,GraffitiErrorForbidden:()=>c,GraffitiErrorInvalidSchema:()=>f,GraffitiErrorInvalidUri:()=>S,GraffitiErrorNotFound:()=>n,GraffitiErrorPatchError:()=>p,GraffitiErrorPatchTestFailed:()=>h,GraffitiErrorSchemaMismatch:()=>m,GraffitiErrorUnauthorized:()=>o});module.exports=j(y);var a=class{objectToUri(t){return this.locationToUri(t)}};var o=class e extends Error{constructor(t){super(t),this.name="GraffitiErrorUnauthorized",Object.setPrototypeOf(this,e.prototype)}},c=class e extends Error{constructor(t){super(t),this.name="GraffitiErrorForbidden",Object.setPrototypeOf(this,e.prototype)}},n=class e extends Error{constructor(t){super(t),this.name="GraffitiErrorNotFound",Object.setPrototypeOf(this,e.prototype)}},f=class e extends Error{constructor(t){super(t),this.name="GraffitiErrorInvalidSchema",Object.setPrototypeOf(this,e.prototype)}},m=class e extends Error{constructor(t){super(t),this.name="GraffitiErrorSchemaMismatch",Object.setPrototypeOf(this,e.prototype)}},h=class e extends Error{constructor(t){super(t),this.name="GraffitiErrorPatchTestFailed",Object.setPrototypeOf(this,e.prototype)}},p=class e extends Error{constructor(t){super(t),this.name="GraffitiErrorPatchError",Object.setPrototypeOf(this,e.prototype)}},S=class e extends Error{constructor(t){super(t),this.name="GraffitiErrorInvalidUri",Object.setPrototypeOf(this,e.prototype)}};
|
|
2
|
-
//# sourceMappingURL=index.cjs.
|
|
2
|
+
//# sourceMappingURL=index.cjs.map
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
var r=class{objectToUri(t){return this.locationToUri(t)}};var s=class e extends Error{constructor(t){super(t),this.name="GraffitiErrorUnauthorized",Object.setPrototypeOf(this,e.prototype)}},i=class e extends Error{constructor(t){super(t),this.name="GraffitiErrorForbidden",Object.setPrototypeOf(this,e.prototype)}},a=class e extends Error{constructor(t){super(t),this.name="GraffitiErrorNotFound",Object.setPrototypeOf(this,e.prototype)}},o=class e extends Error{constructor(t){super(t),this.name="GraffitiErrorInvalidSchema",Object.setPrototypeOf(this,e.prototype)}},c=class e extends Error{constructor(t){super(t),this.name="GraffitiErrorSchemaMismatch",Object.setPrototypeOf(this,e.prototype)}},n=class e extends Error{constructor(t){super(t),this.name="GraffitiErrorPatchTestFailed",Object.setPrototypeOf(this,e.prototype)}},f=class e extends Error{constructor(t){super(t),this.name="GraffitiErrorPatchError",Object.setPrototypeOf(this,e.prototype)}},m=class e extends Error{constructor(t){super(t),this.name="GraffitiErrorInvalidUri",Object.setPrototypeOf(this,e.prototype)}};export{r as Graffiti,i as GraffitiErrorForbidden,o as GraffitiErrorInvalidSchema,m as GraffitiErrorInvalidUri,a as GraffitiErrorNotFound,f as GraffitiErrorPatchError,n as GraffitiErrorPatchTestFailed,c as GraffitiErrorSchemaMismatch,s as GraffitiErrorUnauthorized};
|
|
2
|
-
//# sourceMappingURL=index.
|
|
2
|
+
//# sourceMappingURL=index.mjs.map
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import{it as z,expect as C,describe as L}from"vitest";import{GraffitiErrorInvalidUri as J}from"@graffiti-garden/api";import{assert as N}from"vitest";function u(){let h=new Uint8Array(16);return crypto.getRandomValues(h),Array.from(h).map(q=>q.toString(16).padStart(2,"0")).join("")+"\u{1F469}\u{1F3FD}\u200D\u2764\uFE0F\u200D\u{1F48B}\u200D\u{1F469}\u{1F3FB}\u{1FAF1}\u{1F3FC}\u200D\u{1FAF2}\u{1F3FF}"}function F(){return{[u()]:u()}}function w(){return{value:F(),channels:[u(),u()]}}async function y(h){let p=await h.next();return N(!p.done&&!p.value.error,"result has no value"),p.value.value}var st=h=>{L("URI and location conversion",()=>{z("location to uri and back",async()=>{let p=h(),q={name:u(),actor:u(),source:u()},t=p.locationToUri(q),o=p.uriToLocation(t);C(q).toEqual(o)}),z("collision resistance",async()=>{let p=h(),q={name:u(),actor:u(),source:u()};for(let t of["name","actor","source"]){let o={...q,[t]:u()},e=p.locationToUri(q),a=p.locationToUri(o);C(e).not.toEqual(a)}}),z("random URI should not be a valid location",async()=>{let p=h();C(()=>p.uriToLocation("")).toThrow(J)})})};import{it as x,expect as d,describe as $}from"vitest";import{GraffitiErrorNotFound as O,GraffitiErrorSchemaMismatch as K,GraffitiErrorInvalidSchema as Q,GraffitiErrorForbidden as S,GraffitiErrorPatchTestFailed as W,GraffitiErrorPatchError as R}from"@graffiti-garden/api";var ut=(h,p,q)=>{$("CRUD",{timeout:2e4},()=>{x("put, get, delete",async()=>{let t=h(),o=p(),e={something:"hello, world~ c:"},a=[u(),u()],n=await t.put({value:e,channels:a},o);d(n.value).toEqual({}),d(n.channels).toEqual([]),d(n.allowed).toBeUndefined(),d(n.actor).toEqual(o.actor);let r=await t.get(n,{});d(r.value).toEqual(e),d(r.channels).toEqual([]),d(r.allowed).toBeUndefined(),d(r.name).toEqual(n.name),d(r.actor).toEqual(n.actor),d(r.source).toEqual(n.source),d(r.lastModified).toEqual(n.lastModified);let s={something:"goodbye, world~ :c"},l=await t.put({...n,value:s,channels:[]},o);d(l.value).toEqual(e),d(l.tombstone).toEqual(!0),d(l.name).toEqual(n.name),d(l.actor).toEqual(n.actor),d(l.source).toEqual(n.source),d(l.lastModified).toBeGreaterThan(r.lastModified);let i=await t.get(n,{});d(i.value).toEqual(s),d(i.lastModified).toEqual(l.lastModified),d(i.tombstone).toEqual(!1);let m=await t.delete(i,o);d(m.tombstone).toEqual(!0),d(m.value).toEqual(s),d(m.lastModified).toBeGreaterThan(l.lastModified);let f=await t.get(i,{});d(f).toEqual(m)}),x("get non-existant",async()=>{let t=h(),o=p(),e=await t.put(w(),o);await d(t.get({...e,name:u()},{})).rejects.toBeInstanceOf(O)}),x("put, get, delete with wrong actor",async()=>{let t=h(),o=p(),e=q();await d(t.put({value:{},channels:[],actor:e.actor},o)).rejects.toThrow(S);let a=await t.put({value:{},channels:[]},e);await d(t.delete(a,o)).rejects.toThrow(S),await d(t.patch({},a,o)).rejects.toThrow(S)}),x("put and get with schema",async()=>{let t=h(),o=p(),e={properties:{value:{properties:{something:{type:"string"},another:{type:"integer"}}}}},a={something:"hello",another:42},n=await t.put({value:a,channels:[]},o),r=await t.get(n,e);d(r.value.something).toEqual(a.something),d(r.value.another).toEqual(a.another)}),x("put and get with invalid schema",async()=>{let t=h(),o=p(),e=await t.put({value:{},channels:[]},o);await d(t.get(e,{properties:{value:{type:"asdf"}}})).rejects.toThrow(Q)}),x("put and get with wrong schema",async()=>{let t=h(),o=p(),e=await t.put({value:{hello:"world"},channels:[]},o);await d(t.get(e,{properties:{value:{properties:{hello:{type:"number"}}}}})).rejects.toThrow(K)}),x("put and get with empty access control",async()=>{let t=h(),o=p(),e=q(),a={um:"hi"},n=[u()],r=[u()],s=await t.put({value:a,allowed:n,channels:r},o),l=await t.get(s,{},o);d(l.value).toEqual(a),d(l.allowed).toEqual(n),d(l.channels).toEqual(r),await d(t.get(s,{})).rejects.toBeInstanceOf(O),await d(t.get(s,{},e)).rejects.toBeInstanceOf(O)}),x("put and get with specific access control",async()=>{let t=h(),o=p(),e=q(),a={um:"hi"},n=[u(),e.actor,u()],r=[u()],s=await t.put({value:a,allowed:n,channels:r},o),l=await t.get(s,{},o);d(l.value).toEqual(a),d(l.allowed).toEqual(n),d(l.channels).toEqual(r),await d(t.get(s,{})).rejects.toBeInstanceOf(O);let i=await t.get(s,{},e);d(i.value).toEqual(a),d(i.allowed).toEqual([e.actor]),d(i.channels).toEqual([])}),x("patch value",async()=>{let t=h(),o=p(),e={something:"hello, world~ c:"},a=await t.put({value:e,channels:[]},o),n={value:[{op:"replace",path:"/something",value:"goodbye, world~ :c"}]},r=await t.patch(n,a,o);d(r.value).toEqual(e),d(r.tombstone).toBe(!0);let s=await t.get(a,{});d(s.value).toEqual({something:"goodbye, world~ :c"}),d(r.lastModified).toBe(s.lastModified),await t.delete(a,o)}),x("patch deleted object",async()=>{let t=h(),o=p(),e=await t.put(w(),o),a=await t.delete(e,o);await d(t.patch({},e,o)).rejects.toBeInstanceOf(O)}),x("deep patch",async()=>{let t=h(),o=p(),e={something:{another:{somethingElse:"hello"}}},a=await t.put({value:e,channels:[]},o),n=await t.patch({value:[{op:"replace",path:"/something/another/somethingElse",value:"goodbye"}]},a,o),r=await t.get(a,{});d(n.value).toEqual(e),d(r.value).toEqual({something:{another:{somethingElse:"goodbye"}}})}),x("patch channels",async()=>{let t=h(),o=p(),e=[u()],a=[u()],n=await t.put({value:{},channels:e},o),r={channels:[{op:"replace",path:"/0",value:a[0]}]},s=await t.patch(r,n,o);d(s.channels).toEqual(e);let l=await t.get(n,{},o);d(l.channels).toEqual(a),await t.delete(n,o)}),x("patch 'increment' with test",async()=>{let t=h(),o=p(),e=await t.put({value:{counter:1},channels:[]},o),a=await t.patch({value:[{op:"test",path:"/counter",value:1},{op:"replace",path:"/counter",value:2}]},e,o);d(a.value).toEqual({counter:1});let n=await t.get(a,{properties:{value:{properties:{counter:{type:"integer"}}}}});d(n.value.counter).toEqual(2),await d(t.patch({value:[{op:"test",path:"/counter",value:1},{op:"replace",path:"/counter",value:3}]},e,o)).rejects.toThrow(W)}),x("invalid patch",async()=>{let t=h(),o=p(),e=w(),a=await t.put(e,o);await d(t.patch({value:[{op:"add",path:"/root",value:[]},{op:"add",path:"/root/2",value:2}]},a,o)).rejects.toThrow(R)}),x("patch channels to be wrong",async()=>{let t=h(),o=p(),e=w();e.allowed=[u()];let a=await t.put(e,o),n=[{channels:[{op:"replace",path:"",value:null}]},{channels:[{op:"replace",path:"",value:{}}]},{channels:[{op:"replace",path:"",value:["hello",["hi"]]}]},{channels:[{op:"add",path:"/0",value:1}]},{value:[{op:"replace",path:"",value:"not an object"}]},{value:[{op:"replace",path:"",value:null}]},{value:[{op:"replace",path:"",value:[]}]},{allowed:[{op:"replace",path:"",value:{}}]},{allowed:[{op:"replace",path:"",value:["hello",["hi"]]}]}];for(let s of n)await d(t.patch(s,a,o)).rejects.toThrow(R);let r=await t.get(a,{},o);d(r.value).toEqual(e.value),d(r.channels).toEqual(e.channels),d(r.allowed).toEqual(e.allowed),d(r.lastModified).toEqual(a.lastModified)})})};import{it as I,expect as v,describe as D,assert as H}from"vitest";var vt=(h,p,q)=>{D("synchronizeDiscover",()=>{I("get",async()=>{let t=h(),o=p(),e=w(),a=e.channels.slice(1),n=await t.put(e,o),r=h(),s=r.synchronizeDiscover(a,{}).next(),l=await r.get(n,{},o),i=(await s).value;if(!i||i.error)throw new Error("Error in synchronize");v(i.value.value).toEqual(e.value),v(i.value.channels).toEqual(a),v(i.value.tombstone).toBe(!1),v(i.value.lastModified).toEqual(l.lastModified)}),I("put",async()=>{let t=h(),o=p(),e=u(),a=u(),n=u(),r={hello:"world"},s=[e,n],l=await t.put({value:r,channels:s},o),i=t.synchronizeDiscover([e],{}).next(),m=t.synchronizeDiscover([a],{}).next(),f=t.synchronizeDiscover([n],{}).next(),g={goodbye:"world"},E=[a,n];await t.put({...l,value:g,channels:E},o);let b=(await i).value,B=(await m).value,j=(await f).value;if(!b||b.error||!B||B.error||!j||j.error)throw new Error("Error in synchronize");v(b.value.value).toEqual(r),v(b.value.channels).toEqual([e]),v(b.value.tombstone).toBe(!0),v(B.value.value).toEqual(g),v(B.value.channels).toEqual([a]),v(B.value.tombstone).toBe(!1),v(j.value.value).toEqual(g),v(j.value.channels).toEqual([n]),v(j.value.tombstone).toBe(!1),v(b.value.lastModified).toEqual(B.value.lastModified),v(j.value.lastModified).toEqual(B.value.lastModified)}),I("patch",async()=>{let t=h(),o=p(),e=u(),a=u(),n=u(),r={hello:"world"},s=[e,n],l=await t.put({value:r,channels:s},o),i=t.synchronizeDiscover([e],{}).next(),m=t.synchronizeDiscover([a],{}).next(),f=t.synchronizeDiscover([n],{}).next();await t.patch({value:[{op:"add",path:"/something",value:"new value"}],channels:[{op:"add",path:"/-",value:a},{op:"remove",path:`/${s.indexOf(e)}`}]},l,o);let g=(await i).value,E=(await m).value,b=(await f).value;if(!g||g.error||!E||E.error||!b||b.error)throw new Error("Error in synchronize");let B={...r,something:"new value"},j=[n,a];v(g.value.value).toEqual(r),v(g.value.channels).toEqual([e]),v(g.value.tombstone).toBe(!0),v(E.value.value).toEqual(B),v(E.value.channels).toEqual([a]),v(E.value.tombstone).toBe(!1),v(b.value.value).toEqual(B),v(b.value.channels).toEqual([n]),v(b.value.tombstone).toBe(!1),v(g.value.lastModified).toEqual(E.value.lastModified),v(b.value.lastModified).toEqual(E.value.lastModified)}),I("delete",async()=>{let t=h(),o=p(),e=[u(),u(),u()],a={hello:"world"},n=[u(),...e.slice(1)],r=await t.put({value:a,channels:n},o),s=t.synchronizeDiscover(e,{}).next();t.delete(r,o);let l=(await s).value;if(!l||l.error)throw new Error("Error in synchronize");v(l.value.tombstone).toBe(!0),v(l.value.value).toEqual(a),v(l.value.channels).toEqual(e.filter(i=>n.includes(i)))}),I("not allowed",async()=>{let t=h(),o=p(),e=q(),a=[u(),u(),u()],n=a.slice(1),r=t.synchronizeDiscover(n,{},o).next(),s=t.synchronizeDiscover(n,{},e).next(),l=t.synchronizeDiscover(n,{}).next(),i={hello:"world"},m=[u(),e.actor];await t.put({value:i,channels:a,allowed:m},o),await v(Promise.race([l,new Promise((E,b)=>setTimeout(b,100,"Timeout"))])).rejects.toThrow("Timeout");let f=(await r).value,g=(await s).value;if(!f||f.error||!g||g.error)throw new Error("Error in synchronize");v(f.value.value).toEqual(i),v(f.value.allowed).toEqual(m),v(f.value.channels).toEqual(a),v(g.value.value).toEqual(i),v(g.value.allowed).toEqual([e.actor]),v(g.value.channels).toEqual(n)})}),D("synchronizeGet",()=>{I("replace, delete",async()=>{let t=h(),o=p(),e=w(),a=await t.put(e,o),n=t.synchronizeGet(a,{}),r=n.next(),s={goodbye:"world"},l=await t.put({...a,value:s},o),i=(await r).value;H(i&&!i.error),v(i.value.value).toEqual(s),v(i.value.actor).toEqual(o.actor),v(i.value.channels).toEqual([]),v(i.value.tombstone).toBe(!1),v(i.value.lastModified).toEqual(l.lastModified),v(i.value.allowed).toBeUndefined();let m=await t.delete(l,o),f=(await n.next()).value;H(f&&!f.error),v(f.value.tombstone).toBe(!0),v(f.value.lastModified).toEqual(m.lastModified),await t.put(w(),o),await v(Promise.race([n.next(),new Promise((g,E)=>setTimeout(E,100,"Timeout"))])).rejects.toThrow("Timeout")}),I("not allowed",async()=>{let t=h(),o=p(),e=q(),a=w(),n=await t.put(a,o),r=t.synchronizeGet(n,{},o),s=t.synchronizeGet(n,{},e),l=r.next(),i=s.next(),m={goodbye:"world"},f=await t.put({...n,...a,allowed:[],value:m},o),g=(await l).value,E=(await i).value;H(g&&!g.error),H(E&&!E.error),v(g.value.value).toEqual(m),v(E.value.value).toEqual(a.value),v(g.value.actor).toEqual(o.actor),v(E.value.actor).toEqual(o.actor),v(g.value.channels).toEqual(a.channels),v(E.value.channels).toEqual([]),v(g.value.tombstone).toBe(!1),v(E.value.tombstone).toBe(!0),v(g.value.lastModified).toEqual(f.lastModified),v(E.value.lastModified).toEqual(f.lastModified)})})};import{it as M,expect as c,describe as X,assert as U}from"vitest";var gt=(h,p,q)=>{X("discover",{timeout:2e4},()=>{M("discover nothing",async()=>{let o=h().discover([],{});c(await o.next()).toHaveProperty("done",!0)}),M("discover single",async()=>{let t=h(),o=p(),e=w(),a=await t.put(e,o),n=[u(),e.channels[0]],r=t.discover(n,{}),s=await y(r);c(s.value).toEqual(e.value),c(s.channels).toEqual([e.channels[0]]),c(s.allowed).toBeUndefined(),c(s.actor).toEqual(o.actor),c(s.tombstone).toBe(!1),c(s.lastModified).toEqual(a.lastModified);let l=await r.next();c(l.done).toBe(!0)}),M("discover wrong channel",async()=>{let t=h(),o=p(),e=w();await t.put(e,o);let a=t.discover([u()],{});await c(a.next()).resolves.toHaveProperty("done",!0)}),M("discover not allowed",async()=>{let t=h(),o=p(),e=q(),a=w();a.allowed=[u(),u()];let n=await t.put(a,o),r=t.discover(a.channels,{},o),s=await y(r);c(s.value).toEqual(a.value),c(s.channels).toEqual(a.channels),c(s.allowed).toEqual(a.allowed),c(s.actor).toEqual(o.actor),c(s.tombstone).toBe(!1),c(s.lastModified).toEqual(n.lastModified);let l=t.discover(a.channels,{},e);c(await l.next()).toHaveProperty("done",!0);let i=t.discover(a.channels,{});c(await i.next()).toHaveProperty("done",!0)}),M("discover allowed",async()=>{let t=h(),o=p(),e=q(),a=w();a.allowed=[u(),e.actor,u()];let n=await t.put(a,o),r=t.discover(a.channels,{},e),s=await y(r);c(s.value).toEqual(a.value),c(s.allowed).toEqual([e.actor]),c(s.channels).toEqual(a.channels),c(s.actor).toEqual(o.actor),c(s.tombstone).toBe(!1),c(s.lastModified).toEqual(n.lastModified)});for(let t of["name","actor","lastModified"])M(`discover for ${t}`,async()=>{let o=h(),e=p(),a=q(),n=w(),r=await o.put(n,e),s=w();s.channels=n.channels,await new Promise(f=>setTimeout(f,20));let l=await o.put(s,a),i=o.discover(n.channels,{properties:{[t]:{enum:[r[t]]}}}),m=await y(i);c(m.name).toEqual(r.name),c(m.name).not.toEqual(l.name),c(m.value).toEqual(n.value),await c(i.next()).resolves.toHaveProperty("done",!0)});M("discover with lastModified range",async()=>{let t=h(),o=p(),e=w(),a=await t.put(e,o);await new Promise(G=>setTimeout(G,20));let n=await t.put(e,o);c(a.name).not.toEqual(n.name),c(a.lastModified).toBeLessThan(n.lastModified);let r=t.discover([e.channels[0]],{properties:{lastModified:{minimum:n.lastModified,exclusiveMinimum:!0}}});c(await r.next()).toHaveProperty("done",!0);let s=t.discover([e.channels[0]],{properties:{lastModified:{minimum:n.lastModified-.1,exclusiveMinimum:!0}}}),l=await y(s);c(l.name).toEqual(n.name),c(await s.next()).toHaveProperty("done",!0);let i=t.discover(e.channels,{properties:{value:{},lastModified:{minimum:n.lastModified}}}),m=await y(i);c(m.name).toEqual(n.name),c(await i.next()).toHaveProperty("done",!0);let f=t.discover(e.channels,{properties:{lastModified:{minimum:n.lastModified+.1}}});c(await f.next()).toHaveProperty("done",!0);let g=t.discover(e.channels,{properties:{lastModified:{maximum:a.lastModified,exclusiveMaximum:!0}}});c(await g.next()).toHaveProperty("done",!0);let E=t.discover(e.channels,{properties:{lastModified:{maximum:a.lastModified+.1,exclusiveMaximum:!0}}}),b=await y(E);c(b.name).toEqual(a.name),c(await E.next()).toHaveProperty("done",!0);let B=t.discover(e.channels,{properties:{lastModified:{maximum:a.lastModified}}}),j=await y(B);c(j.name).toEqual(a.name),c(await B.next()).toHaveProperty("done",!0);let A=t.discover(e.channels,{properties:{lastModified:{maximum:a.lastModified-.1}}});c(await A.next()).toHaveProperty("done",!0)}),M("discover schema allowed, as and not as owner",async()=>{let t=h(),o=p(),e=q(),a=w();a.allowed=[u(),e.actor,u()],await t.put(a,o);let n=t.discover(a.channels,{properties:{allowed:{minItems:3,not:{items:{not:{enum:[e.actor]}}}}}},o),r=await y(n);c(r.value).toEqual(a.value),await c(n.next()).resolves.toHaveProperty("done",!0);let s=t.discover(a.channels,{properties:{allowed:{minItems:3}}},e);await c(s.next()).resolves.toHaveProperty("done",!0);let l=t.discover(a.channels,{properties:{allowed:{not:{items:{not:{enum:[a.channels[0]]}}}}}},e);await c(l.next()).resolves.toHaveProperty("done",!0);let i=t.discover(a.channels,{properties:{allowed:{maxItems:1,not:{items:{not:{enum:[e.actor]}}}}}},e),m=await y(i);c(m.value).toEqual(a.value),await c(i.next()).resolves.toHaveProperty("done",!0)}),M("discover schema channels, as and not as owner",async()=>{let t=h(),o=p(),e=q(),a=w();a.channels=[u(),u(),u()],await t.put(a,o);let n=t.discover([a.channels[0],a.channels[2]],{properties:{channels:{minItems:3,not:{items:{not:{enum:[a.channels[1]]}}}}}},o),r=await y(n);c(r.value).toEqual(a.value),await c(n.next()).resolves.toHaveProperty("done",!0);let s=t.discover([a.channels[0],a.channels[2]],{properties:{channels:{minItems:3}}},e);await c(s.next()).resolves.toHaveProperty("done",!0);let l=t.discover([a.channels[0],a.channels[2]],{properties:{channels:{not:{items:{not:{enum:[a.channels[1]]}}}}}},e);await c(l.next()).resolves.toHaveProperty("done",!0);let i=t.discover([a.channels[0],a.channels[2]],{properties:{allowed:{maxItems:2,not:{items:{not:{enum:[a.channels[2]]}}}}}},e),m=await y(i);c(m.value).toEqual(a.value),await c(i.next()).resolves.toHaveProperty("done",!0)}),M("discover query for empty allowed",async()=>{let t=h(),o=p(),e=w(),a={not:{required:["allowed"]}};await t.put(e,o);let n=t.discover(e.channels,a,o),r=await y(n);c(r.value).toEqual(e.value),c(r.allowed).toBeUndefined(),await c(n.next()).resolves.toHaveProperty("done",!0);let s=w();s.allowed=[],await t.put(s,o);let l=t.discover(s.channels,a,o);await c(l.next()).resolves.toHaveProperty("done",!0)}),M("discover query for values",async()=>{let t=h(),o=p(),e=w();e.value={test:u()},await t.put(e,o);let a=w();a.channels=e.channels,a.value={test:u(),something:u()},await t.put(a,o);let n=w();n.channels=e.channels,n.value={other:u(),something:u()},await t.put(n,o);let r=new Map;for(let s of["test","something","other"]){let l=0;for await(let i of t.discover(e.channels,{properties:{value:{required:[s]}}}))U(!i.error,"result has error"),s in i.value.value&&l++;r.set(s,l)}c(r.get("test")).toBe(2),c(r.get("something")).toBe(2),c(r.get("other")).toBe(1)}),M("discover for deleted content",async()=>{let t=h(),o=p(),e=w(),a=await t.put(e,o),n=await t.delete(a,o),r=t.discover(e.channels,{}),s=await y(r);c(s.tombstone).toBe(!0),c(s.value).toEqual(e.value),c(s.channels).toEqual(e.channels),c(s.actor).toEqual(o.actor),c(s.lastModified).toEqual(n.lastModified),await c(r.next()).resolves.toHaveProperty("done",!0)}),M("discover for replaced channels",async()=>{for(let t=0;t<10;t++){let o=h(),e=p(),a=w(),n=await o.put(a,e),r=w(),s=await o.put({...n,...r},e),l=o.discover(a.channels,{}),i=await y(l);await c(l.next()).resolves.toHaveProperty("done",!0);let m=o.discover(r.channels,{}),f=await y(m);await c(m.next()).resolves.toHaveProperty("done",!0),n.lastModified===s.lastModified?(c(i.tombstone||f.tombstone).toBe(!0),c(i.tombstone&&f.tombstone).toBe(!1)):(c(i.tombstone).toBe(!0),c(i.value).toEqual(a.value),c(i.channels).toEqual(a.channels),c(i.lastModified).toEqual(s.lastModified),c(f.tombstone).toBe(!1),c(f.value).toEqual(r.value),c(f.channels).toEqual(r.channels),c(f.lastModified).toEqual(s.lastModified))}}),M("discover for patched allowed",async()=>{let t=h(),o=p(),e=w(),a=await t.put(e,o);await t.patch({allowed:[{op:"add",path:"",value:[]}]},a,o);let n=t.discover(e.channels,{}),r=await y(n);c(r.tombstone).toBe(!0),c(r.value).toEqual(e.value),c(r.channels).toEqual(e.channels),c(r.allowed).toBeUndefined(),await c(n.next()).resolves.toHaveProperty("done",!0)}),M("put concurrently and discover one",async()=>{let t=h(),o=p(),e=w();e.name=u();let a=Array(100).fill(0).map(()=>t.put(e,o));await Promise.all(a);let n=t.discover(e.channels,{}),r=0,s=0;for await(let l of n)U(!l.error,"result has error"),l.value.tombstone?r++:s++;c(r).toBe(99),c(s).toBe(1)})})};import{it as V,expect as T,describe as Y}from"vitest";var xt=(h,p,q)=>{Y("recoverOrphans",()=>{V("list orphans",async()=>{let t=h(),o=p(),e=[],a=t.recoverOrphans({},o);for await(let i of a)i.error||e.push(i.value.name);let n=w();n.channels=[];let r=await t.put(n,o),s=t.recoverOrphans({},o),l=0;for await(let i of s)i.error||i.value.name===r.name&&(l++,T(i.value.source).toBe(r.source),T(i.value.lastModified).toBe(r.lastModified));T(l).toBe(1)}),V("replaced orphan, no longer",async()=>{let t=h(),o=p(),e=w();e.channels=[];let a=await t.put(e,o),n=await t.put({...a,...e,channels:[u()]},o);T(n.name).toBe(a.name);let r=t.recoverOrphans({},o),s=0;for await(let l of r)l.error||l.value.name===a.name&&(s++,T(l.value.tombstone).toBe(!0),T(l.value.lastModified).toBe(n.lastModified),T(l.value.channels).toEqual([]));T(s).toBe(1)})})};import{it as k,expect as P,describe as Z,assert as _}from"vitest";var Tt=(h,p,q)=>{Z("channel stats",()=>{k("list channels",async()=>{let t=h(),o=p(),e=new Map,a=t.channelStats(o);for await(let l of a)l.error||e.set(l.value.channel,l.value.count);let n=[u(),u(),u()];for(let l=0;l<3;l++)for(let i=0;i<l+1;i++)await t.put({value:{index:i},channels:n.slice(0,l+1)},o);await t.put({value:{index:3},channels:[n[2]]},o);let r=t.channelStats(o),s=new Map;for await(let l of r)l.error||s.set(l.value.channel,l.value.count);s=new Map(Array.from(s).filter(([l,i])=>!e.has(l))),P(s.size).toBe(3),P(s.get(n[0])).toBe(6),P(s.get(n[1])).toBe(5),P(s.get(n[2])).toBe(4)}),k("list channels with deleted channel",async()=>{let t=h(),o=p(),e=[u(),u(),u()],a=await t.put({value:{index:2},channels:e.slice(1)},o),n=await t.put({value:{index:0},channels:e},o);await t.delete(n,o);let r=await t.put({value:{index:1},channels:e.slice(2)},o),s=t.channelStats(o),l=0,i=0;for await(let m of s){if(m.error)continue;let{channel:f,count:g,lastModified:E}=m.value;_(f!==e[0],"There should not be an object in channel[0]"),f===e[1]?(P(g).toBe(1),P(E).toBe(a.lastModified),l++):f===e[2]&&(P(g).toBe(2),P(E).toBe(r.lastModified),i++)}P(l).toBe(1),P(i).toBe(1)})})};export{ut as graffitiCRUDTests,Tt as graffitiChannelStatsTests,gt as graffitiDiscoverTests,st as graffitiLocationTests,xt as graffitiOrphanTests,vt as graffitiSynchronizeTests};
|
|
2
|
-
//# sourceMappingURL=tests.
|
|
2
|
+
//# sourceMappingURL=tests.mjs.map
|
package/package.json
CHANGED
|
@@ -1,25 +1,25 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@graffiti-garden/api",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.5",
|
|
4
4
|
"description": "The heart of Graffiti",
|
|
5
|
-
"type": "module",
|
|
6
5
|
"types": "./dist/src/index.d.ts",
|
|
7
|
-
"module": "./dist/index.
|
|
8
|
-
"main": "./dist/index.cjs
|
|
6
|
+
"module": "./dist/index.mjs",
|
|
7
|
+
"main": "./dist/index.cjs",
|
|
9
8
|
"exports": {
|
|
10
9
|
".": {
|
|
11
10
|
"import": {
|
|
12
11
|
"types": "./dist/src/index.d.ts",
|
|
13
|
-
"
|
|
12
|
+
"node": "./dist/index.cjs",
|
|
13
|
+
"default": "./dist/index.mjs"
|
|
14
14
|
},
|
|
15
15
|
"require": {
|
|
16
16
|
"types": "./dist/src/index.d.ts",
|
|
17
|
-
"default": "./dist/index.cjs
|
|
17
|
+
"default": "./dist/index.cjs"
|
|
18
18
|
}
|
|
19
19
|
},
|
|
20
20
|
"./tests": {
|
|
21
21
|
"types": "./dist/tests/index.d.ts",
|
|
22
|
-
"default": "./dist/tests.
|
|
22
|
+
"default": "./dist/tests.mjs"
|
|
23
23
|
}
|
|
24
24
|
},
|
|
25
25
|
"files": [
|
|
@@ -33,7 +33,7 @@
|
|
|
33
33
|
"license": "GPL-3.0-or-later",
|
|
34
34
|
"scripts": {
|
|
35
35
|
"build:types": "tsc --declaration --emitDeclarationOnly",
|
|
36
|
-
"build:js": "tsx esbuild.config.
|
|
36
|
+
"build:js": "tsx esbuild.config.mts",
|
|
37
37
|
"build": "rm -rf dist && npm run build:types && npm run build:js",
|
|
38
38
|
"docs": "typedoc --options typedoc.json",
|
|
39
39
|
"prepublishOnly": "npm update && npm run build"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|