@graffiti-garden/api 0.1.4 → 0.1.6
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/src/1-api.d.ts.map +1 -0
- package/dist/src/2-types.d.ts.map +1 -0
- package/dist/src/3-errors.d.ts.map +1 -0
- package/dist/src/index.d.ts.map +1 -0
- package/dist/tests/index.js +1 -1
- package/dist/{types/tests → tests/src}/crud.d.ts +1 -1
- package/dist/tests/src/crud.d.ts.map +1 -0
- package/dist/{types/tests → tests/src}/discover.d.ts +1 -1
- package/dist/tests/src/discover.d.ts.map +1 -0
- package/dist/tests/src/index.d.ts.map +1 -0
- package/dist/tests/src/location.d.ts +3 -0
- package/dist/tests/src/location.d.ts.map +1 -0
- package/dist/tests/src/src/crud.d.ts +3 -0
- package/dist/tests/src/src/crud.d.ts.map +1 -0
- package/dist/tests/src/src/discover.d.ts +3 -0
- package/dist/tests/src/src/discover.d.ts.map +1 -0
- package/dist/tests/src/src/index.d.ts +5 -0
- package/dist/tests/src/src/index.d.ts.map +1 -0
- package/dist/tests/src/src/location.d.ts +3 -0
- package/dist/tests/src/src/location.d.ts.map +1 -0
- package/dist/{types/tests → tests/src/src}/synchronize.d.ts +1 -1
- package/dist/tests/src/src/synchronize.d.ts.map +1 -0
- package/dist/{types/tests → tests/src/src}/utils.d.ts +1 -1
- package/dist/tests/src/src/utils.d.ts.map +1 -0
- package/dist/tests/src/synchronize.d.ts +3 -0
- package/dist/tests/src/synchronize.d.ts.map +1 -0
- package/dist/tests/src/utils.d.ts +8 -0
- package/dist/tests/src/utils.d.ts.map +1 -0
- package/package.json +9 -14
- package/tests/rollup.config.ts +19 -0
- package/tests/{crud.ts → src/crud.ts} +1 -1
- package/tests/{discover.ts → src/discover.ts} +5 -6
- package/tests/{location.ts → src/location.ts} +4 -1
- package/tests/{synchronize.ts → src/synchronize.ts} +1 -1
- package/tests/{utils.ts → src/utils.ts} +1 -1
- package/tests/tsconfig.json +16 -0
- package/dist/tests/index.cjs.js +0 -2
- package/dist/tests/index.cjs.js.map +0 -1
- package/dist/types/src/1-api.d.ts.map +0 -1
- package/dist/types/src/2-types.d.ts.map +0 -1
- package/dist/types/src/3-errors.d.ts.map +0 -1
- package/dist/types/src/index.d.ts.map +0 -1
- package/dist/types/tests/crud.d.ts.map +0 -1
- package/dist/types/tests/discover.d.ts.map +0 -1
- package/dist/types/tests/index.d.ts.map +0 -1
- package/dist/types/tests/location.d.ts +0 -3
- package/dist/types/tests/location.d.ts.map +0 -1
- package/dist/types/tests/synchronize.d.ts.map +0 -1
- package/dist/types/tests/utils.d.ts.map +0 -1
- /package/dist/{types/src → src}/1-api.d.ts +0 -0
- /package/dist/{types/src → src}/2-types.d.ts +0 -0
- /package/dist/{types/src → src}/3-errors.d.ts +0 -0
- /package/dist/{types/src → src}/index.d.ts +0 -0
- /package/dist/{types/tests → tests/src}/index.d.ts +0 -0
- /package/tests/{index.ts → src/index.ts} +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"1-api.d.ts","sourceRoot":"","sources":["../../src/1-api.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"2-types.d.ts","sourceRoot":"","sources":["../../src/2-types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AACjD,OAAO,KAAK,EAAE,SAAS,IAAI,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AAEvE;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,MAAM,WAAW,kBAAkB;IACjC;;;;;OAKG;IACH,KAAK,EAAE,EAAE,CAAC;IAEV;;;;;;;;;;;;OAYG;IACH,QAAQ,EAAE,MAAM,EAAE,CAAC;IAEnB;;;;;;;;;;;;;OAaG;IACH,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IAEnB;;;;;;;;;;;;OAYG;IACH,KAAK,EAAE,MAAM,CAAC;IAEd;;;;;;OAMG;IACH,IAAI,EAAE,MAAM,CAAC;IAEb;;;;;OAKG;IACH,MAAM,EAAE,MAAM,CAAC;IAEf;;;;;;;;;OASG;IACH,YAAY,EAAE,MAAM,CAAC;IAErB;;;OAGG;IACH,SAAS,EAAE,OAAO,CAAC;CACpB;AAED;;;;;;;GAOG;AACH,MAAM,MAAM,cAAc,CAAC,MAAM,IAAI,kBAAkB,GAAG,WAAW,CAAC,MAAM,CAAC,CAAC;AAE9E;;;;;;;;;GASG;AACH,MAAM,MAAM,gBAAgB,GAAG,IAAI,CACjC,kBAAkB,EAClB,OAAO,GAAG,MAAM,GAAG,QAAQ,CAC5B,CAAC;AAEF;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,MAAM,iBAAiB,CAAC,MAAM,IAAI,IAAI,CAC1C,kBAAkB,EAClB,OAAO,GAAG,UAAU,GAAG,SAAS,CACjC,GACC,OAAO,CAAC,gBAAgB,CAAC,GACzB,WAAW,CAAC,MAAM,CAAC,CAAC;AAEtB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,MAAM,WAAW,eAAe;IAC9B;;OAEG;IACH,KAAK,EAAE,MAAM,CAAC;IACd;;;;;OAKG;IACH,KAAK,CAAC,EAAE,EAAE,CAAC;CACZ;AAED;;;;;;;;;GASG;AACH,MAAM,WAAW,aAAa;IAC5B;;;;OAIG;IACH,KAAK,CAAC,EAAE,kBAAkB,EAAE,CAAC;IAE7B;;;;OAIG;IACH,QAAQ,CAAC,EAAE,kBAAkB,EAAE,CAAC;IAEhC;;;;OAIG;IACH,OAAO,CAAC,EAAE,kBAAkB,EAAE,CAAC;CAChC;AAED;;;;;;;;;;;;;;;GAeG;AACH,MAAM,MAAM,cAAc,CAAC,MAAM,EAAE,OAAO,GAAG,IAAI,IAAI,cAAc,CAC/D;IACE,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;CACf,GACD;IACE,KAAK,EAAE,KAAK,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;CAChB,EACH,OAAO,CACR,CAAC;AAEF;;;;;GAKG;AACH,MAAM,MAAM,kBAAkB,GAAG,WAAW,CAC1C;IACE,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,GAAG,CACA;IACE,KAAK,EAAE,KAAK,CAAC;IACb,OAAO,CAAC,EAAE,SAAS,CAAC;CACrB,GACD;IACE,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB,OAAO,EAAE,eAAe,CAAC;CAC1B,CACJ,CACF,CAAC;AAEF;;;;;GAKG;AACH,MAAM,MAAM,mBAAmB,GAAG,WAAW,CAAC;IAC5C,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,KAAK,CAAC;CACf,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"3-errors.d.ts","sourceRoot":"","sources":["../../src/3-errors.ts"],"names":[],"mappings":"AAAA,qBAAa,yBAA0B,SAAQ,KAAK;gBACtC,OAAO,CAAC,EAAE,MAAM;CAK7B;AAED,qBAAa,sBAAuB,SAAQ,KAAK;gBACnC,OAAO,CAAC,EAAE,MAAM;CAK7B;AAED,qBAAa,qBAAsB,SAAQ,KAAK;gBAClC,OAAO,CAAC,EAAE,MAAM;CAK7B;AAED,qBAAa,0BAA2B,SAAQ,KAAK;gBACvC,OAAO,CAAC,EAAE,MAAM;CAK7B;AAED,qBAAa,2BAA4B,SAAQ,KAAK;gBACxC,OAAO,CAAC,EAAE,MAAM;CAK7B;AAED,qBAAa,4BAA6B,SAAQ,KAAK;gBACzC,OAAO,CAAC,EAAE,MAAM;CAK7B;AAED,qBAAa,uBAAwB,SAAQ,KAAK;gBACpC,OAAO,CAAC,EAAE,MAAM;CAK7B;AAED,qBAAa,uBAAwB,SAAQ,KAAK;gBACpC,OAAO,CAAC,EAAE,MAAM;CAK7B"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,SAAS,CAAC;AACxB,cAAc,WAAW,CAAC;AAC1B,cAAc,YAAY,CAAC;AAC3B,YAAY,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC"}
|
package/dist/tests/index.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{assert as e,describe as a,it as t,expect as o}from"vitest";class n extends Error{constructor(e){super(e),this.name="GraffitiErrorForbidden",Object.setPrototypeOf(this,n.prototype)}}class l extends Error{constructor(e){super(e),this.name="GraffitiErrorNotFound",Object.setPrototypeOf(this,l.prototype)}}class s extends Error{constructor(e){super(e),this.name="GraffitiErrorInvalidSchema",Object.setPrototypeOf(this,s.prototype)}}class r extends Error{constructor(e){super(e),this.name="GraffitiErrorSchemaMismatch",Object.setPrototypeOf(this,r.prototype)}}class i extends Error{constructor(e){super(e),this.name="GraffitiErrorPatchTestFailed",Object.setPrototypeOf(this,i.prototype)}}class c extends Error{constructor(e){super(e),this.name="GraffitiErrorPatchError",Object.setPrototypeOf(this,c.prototype)}}class u extends Error{constructor(e){super(e),this.name="GraffitiErrorInvalidUri",Object.setPrototypeOf(this,u.prototype)}}function d(){const e=new Uint8Array(16);return crypto.getRandomValues(e),Array.from(e).map((e=>e.toString(16).padStart(2,"0"))).join("")}function v(){return{value:{[d()]:d()},channels:[d(),d()]}}async function h(a){const t=await a.next();return e(!t.done&&!t.value.error,"result has no value"),t.value.value}const p=e=>{a("URI and location conversion",(()=>{t("location to uri and back",(async()=>{const a=e(),t={name:d(),actor:d(),source:d()},n=a.locationToUri(t),l=a.uriToLocation(n);o(t).toEqual(l)})),t("collision resistance",(async()=>{const a=e(),t={name:d(),actor:d(),source:d()};for(const e of["name","actor","source"]){const n={...t,[e]:d()},l=a.locationToUri(t),s=a.locationToUri(n);o(l).not.toEqual(s)}})),t("random URI should not be a valid location",(async()=>{const a=e();o((()=>a.uriToLocation(""))).toThrow(u)}))}))},w=(e,u,h)=>{a("CRUD",(()=>{t("put, get, delete",(async()=>{const a=e(),t=u(),n={something:"hello, world~ c:"},s=[d(),d()],r=await a.put({value:n,channels:s},t);o(r.value).toEqual({}),o(r.channels).toEqual([]),o(r.allowed).toBeUndefined(),o(r.actor).toEqual(t.actor);const i=await a.get(r,{});o(i.value).toEqual(n),o(i.channels).toEqual([]),o(i.allowed).toBeUndefined(),o(i.name).toEqual(r.name),o(i.actor).toEqual(r.actor),o(i.source).toEqual(r.source),o(i.lastModified).toEqual(r.lastModified);const c={something:"goodbye, world~ :c"},v=await a.put({...r,value:c,channels:[]},t);o(v.value).toEqual(n),o(v.tombstone).toEqual(!0),o(v.name).toEqual(r.name),o(v.actor).toEqual(r.actor),o(v.source).toEqual(r.source),o(v.lastModified).toBeGreaterThan(i.lastModified);const h=await a.get(r,{});o(h.value).toEqual(c),o(h.lastModified).toEqual(v.lastModified),o(h.tombstone).toEqual(!1);const p=await a.delete(h,t);o(p.tombstone).toEqual(!0),o(p.value).toEqual(c),o(p.lastModified).toBeGreaterThan(v.lastModified),await o(a.get(h,{})).rejects.toThrow(l)})),t("put, get, delete with wrong actor",(async()=>{const a=e(),t=u(),l=h();await o(a.put({value:{},channels:[],actor:l.actor},t)).rejects.toThrow(n),await o(a.delete({name:"asdf",source:"asdf",actor:l.actor},t)).rejects.toThrow(n),await o(a.patch({},{name:"asdf",source:"asdf",actor:l.actor},t)).rejects.toThrow(n)})),t("put and get with schema",(async()=>{const a=e(),t=u(),n={something:"hello",another:42},l=await a.put({value:n,channels:[]},t),s=await a.get(l,{properties:{value:{properties:{something:{type:"string"},another:{type:"integer"}}}}});o(s.value.something).toEqual(n.something),o(s.value.another).toEqual(n.another)})),t("put and get with invalid schema",(async()=>{const a=e(),t=u(),n=await a.put({value:{},channels:[]},t);await o(a.get(n,{properties:{value:{type:"asdf"}}})).rejects.toThrow(s)})),t("put and get with wrong schema",(async()=>{const a=e(),t=u(),n=await a.put({value:{hello:"world"},channels:[]},t);await o(a.get(n,{properties:{value:{properties:{hello:{type:"number"}}}}})).rejects.toThrow(r)})),t("put and get with empty access control",(async()=>{const a=e(),t=u(),n=h(),l={um:"hi"},s=[d()],r=[d()],i=await a.put({value:l,allowed:s,channels:r},t),c=await a.get(i,{},t);o(c.value).toEqual(l),o(c.allowed).toEqual(s),o(c.channels).toEqual(r),await o(a.get(i,{})).rejects.toThrow(),await o(a.get(i,{},n)).rejects.toThrow()})),t("put and get with specific access control",(async()=>{const a=e(),t=u(),n=h(),l={um:"hi"},s=[d(),n.actor,d()],r=[d()],i=await a.put({value:l,allowed:s,channels:r},t),c=await a.get(i,{},t);o(c.value).toEqual(l),o(c.allowed).toEqual(s),o(c.channels).toEqual(r),await o(a.get(i,{})).rejects.toThrow();const v=await a.get(i,{},n);o(v.value).toEqual(l),o(v.allowed).toEqual([n.actor]),o(v.channels).toEqual([])})),t("patch value",(async()=>{const a=e(),t=u(),n={something:"hello, world~ c:"},l=await a.put({value:n,channels:[]},t),s=await a.patch({value:[{op:"replace",path:"/something",value:"goodbye, world~ :c"}]},l,t);o(s.value).toEqual(n),o(s.tombstone).toBe(!0);const r=await a.get(l,{});o(r.value).toEqual({something:"goodbye, world~ :c"}),o(s.lastModified).toBe(r.lastModified),await a.delete(l,t)})),t("deep patch",(async()=>{const a=e(),t=u(),n={something:{another:{somethingElse:"hello"}}},l=await a.put({value:n,channels:[]},t),s=await a.patch({value:[{op:"replace",path:"/something/another/somethingElse",value:"goodbye"}]},l,t),r=await a.get(l,{});o(s.value).toEqual(n),o(r.value).toEqual({something:{another:{somethingElse:"goodbye"}}})})),t("patch channels",(async()=>{const a=e(),t=u(),n=[d()],l=[d()],s=await a.put({value:{},channels:n},t),r={channels:[{op:"replace",path:"/0",value:l[0]}]},i=await a.patch(r,s,t);o(i.channels).toEqual(n);const c=await a.get(s,{},t);o(c.channels).toEqual(l),await a.delete(s,t)})),t("patch 'increment' with test",(async()=>{const a=e(),t=u(),n=await a.put({value:{counter:1},channels:[]},t),l=await a.patch({value:[{op:"test",path:"/counter",value:1},{op:"replace",path:"/counter",value:2}]},n,t);o(l.value).toEqual({counter:1});const s=await a.get(l,{properties:{value:{properties:{counter:{type:"integer"}}}}});o(s.value.counter).toEqual(2),await o(a.patch({value:[{op:"test",path:"/counter",value:1},{op:"replace",path:"/counter",value:3}]},n,t)).rejects.toThrow(i)})),t("invalid patch",(async()=>{const a=e(),t=u(),n=v(),l=await a.put(n,t);await o(a.patch({value:[{op:"add",path:"/root",value:[]},{op:"add",path:"/root/2",value:2}]},l,t)).rejects.toThrow(c)})),t("patch channels to be wrong",(async()=>{const a=e(),t=u(),n=v();n.allowed=[d()];const l=await a.put(n,t),s=[{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(const e of s)await o(a.patch(e,l,t)).rejects.toThrow(c);const r=await a.get(l,{},t);o(r.value).toEqual(n.value),o(r.channels).toEqual(n.channels),o(r.allowed).toEqual(n.allowed),o(r.lastModified).toEqual(l.lastModified)}))}))},m=(e,n,l)=>{a("synchronize",(()=>{t("get",(async()=>{const a=e(),t=n(),l=v(),s=l.channels.slice(1),r=await a.put(l,t),i=e(),c=i.synchronize(s,{}).next(),u=await i.get(r,{},t),d=(await c).value;if(!d||d.error)throw new Error("Error in synchronize");o(d.value.value).toEqual(l.value),o(d.value.channels).toEqual(s),o(d.value.tombstone).toBe(!1),o(d.value.lastModified).toEqual(u.lastModified)})),t("put",(async()=>{const a=e(),t=n(),l=d(),s=d(),r=d(),i={hello:"world"},c=[l,r],u=await a.put({value:i,channels:c},t),v=a.synchronize([l],{}).next(),h=a.synchronize([s],{}).next(),p=a.synchronize([r],{}).next(),w={goodbye:"world"},m=[s,r];await a.put({...u,value:w,channels:m},t);const E=(await v).value,f=(await h).value,y=(await p).value;if(!E||E.error||!f||f.error||!y||y.error)throw new Error("Error in synchronize");o(E.value.value).toEqual(i),o(E.value.channels).toEqual([l]),o(E.value.tombstone).toBe(!0),o(f.value.value).toEqual(w),o(f.value.channels).toEqual([s]),o(f.value.tombstone).toBe(!1),o(y.value.value).toEqual(w),o(y.value.channels).toEqual([r]),o(y.value.tombstone).toBe(!1),o(E.value.lastModified).toEqual(f.value.lastModified),o(y.value.lastModified).toEqual(f.value.lastModified)})),t("patch",(async()=>{const a=e(),t=n(),l=d(),s=d(),r=d(),i={hello:"world"},c=[l,r],u=await a.put({value:i,channels:c},t),v=a.synchronize([l],{}).next(),h=a.synchronize([s],{}).next(),p=a.synchronize([r],{}).next();await a.patch({value:[{op:"add",path:"/something",value:"new value"}],channels:[{op:"add",path:"/-",value:s},{op:"remove",path:`/${c.indexOf(l)}`}]},u,t);const w=(await v).value,m=(await h).value,E=(await p).value;if(!w||w.error||!m||m.error||!E||E.error)throw new Error("Error in synchronize");const f={...i,something:"new value"};o(w.value.value).toEqual(i),o(w.value.channels).toEqual([l]),o(w.value.tombstone).toBe(!0),o(m.value.value).toEqual(f),o(m.value.channels).toEqual([s]),o(m.value.tombstone).toBe(!1),o(E.value.value).toEqual(f),o(E.value.channels).toEqual([r]),o(E.value.tombstone).toBe(!1),o(w.value.lastModified).toEqual(m.value.lastModified),o(E.value.lastModified).toEqual(m.value.lastModified)})),t("delete",(async()=>{const a=e(),t=n(),l=[d(),d(),d()],s={hello:"world"},r=[d(),...l.slice(1)],i=await a.put({value:s,channels:r},t),c=a.synchronize(l,{}).next();a.delete(i,t);const u=(await c).value;if(!u||u.error)throw new Error("Error in synchronize");o(u.value.tombstone).toBe(!0),o(u.value.value).toEqual(s),o(u.value.channels).toEqual(l.filter((e=>r.includes(e))))})),t("not allowed",(async()=>{const a=e(),t=n(),s=l(),r=[d(),d(),d()],i=r.slice(1),c=a.synchronize(i,{},t).next(),u=a.synchronize(i,{},s).next(),v=a.synchronize(i,{}).next(),h={hello:"world"},p=[d(),s.actor];await a.put({value:h,channels:r,allowed:p},t),await o(Promise.race([v,new Promise(((e,a)=>setTimeout(a,100,"Timeout")))])).rejects.toThrow("Timeout");const w=(await c).value,m=(await u).value;if(!w||w.error||!m||m.error)throw new Error("Error in synchronize");o(w.value.value).toEqual(h),o(w.value.allowed).toEqual(p),o(w.value.channels).toEqual(r),o(m.value.value).toEqual(h),o(m.value.allowed).toEqual([s.actor]),o(m.value.channels).toEqual(i)}))}))},E=(n,l,s)=>{a("discover",(()=>{t("discover nothing",(async()=>{const e=n().discover([],{});o(await e.next()).toHaveProperty("done",!0)})),t("discover single",(async()=>{const e=n(),a=l(),t=v(),s=await e.put(t,a),r=[d(),t.channels[0]],i=e.discover(r,{}),c=await h(i);o(c.value).toEqual(t.value),o(c.channels).toEqual([t.channels[0]]),o(c.allowed).toBeUndefined(),o(c.actor).toEqual(a.actor),o(c.tombstone).toBe(!1),o(c.lastModified).toEqual(s.lastModified);const u=await i.next();o(u.done).toBe(!0)})),t("discover wrong channel",(async()=>{const e=n(),a=l(),t=v();await e.put(t,a);const s=e.discover([d()],{});await o(s.next()).resolves.toHaveProperty("done",!0)})),t("discover not allowed",(async()=>{const e=n(),a=l(),t=s(),r=v();r.allowed=[d(),d()];const i=await e.put(r,a),c=e.discover(r.channels,{},a),u=await h(c);o(u.value).toEqual(r.value),o(u.channels).toEqual(r.channels),o(u.allowed).toEqual(r.allowed),o(u.actor).toEqual(a.actor),o(u.tombstone).toBe(!1),o(u.lastModified).toEqual(i.lastModified);const p=e.discover(r.channels,{},t);o(await p.next()).toHaveProperty("done",!0);const w=e.discover(r.channels,{});o(await w.next()).toHaveProperty("done",!0)})),t("discover allowed",(async()=>{const e=n(),a=l(),t=s(),r=v();r.allowed=[d(),t.actor,d()];const i=await e.put(r,a),c=e.discover(r.channels,{},t),u=await h(c);o(u.value).toEqual(r.value),o(u.allowed).toEqual([t.actor]),o(u.channels).toEqual(r.channels),o(u.actor).toEqual(a.actor),o(u.tombstone).toBe(!1),o(u.lastModified).toEqual(i.lastModified)}));for(const e of["name","actor","lastModified"])t(`discover for ${e}`,(async()=>{const a=n(),t=l(),r=s(),i=v(),c=await a.put(i,t),u=v();u.channels=i.channels,await new Promise((e=>setTimeout(e,20)));const d=await a.put(u,r),p=a.discover(i.channels,{properties:{[e]:{enum:[c[e]]}}}),w=await h(p);o(w.name).toEqual(c.name),o(w.name).not.toEqual(d.name),o(w.value).toEqual(i.value),await o(p.next()).resolves.toHaveProperty("done",!0)}));t("discover with lastModified range",(async()=>{const e=n(),a=l(),t=v(),s=await e.put(t,a);await new Promise((e=>setTimeout(e,20)));const r=await e.put(t,a);o(s.name).not.toEqual(r.name),o(s.lastModified).toBeLessThan(r.lastModified);const i=e.discover([t.channels[0]],{properties:{lastModified:{minimum:r.lastModified,exclusiveMinimum:!0}}});o(await i.next()).toHaveProperty("done",!0);const c=e.discover([t.channels[0]],{properties:{lastModified:{minimum:r.lastModified-.1,exclusiveMinimum:!0}}}),u=await h(c);o(u.name).toEqual(r.name),o(await c.next()).toHaveProperty("done",!0);const d=e.discover(t.channels,{properties:{value:{},lastModified:{minimum:r.lastModified}}}),p=await h(d);o(p.name).toEqual(r.name),o(await d.next()).toHaveProperty("done",!0);const w=e.discover(t.channels,{properties:{lastModified:{minimum:r.lastModified+.1}}});o(await w.next()).toHaveProperty("done",!0);const m=e.discover(t.channels,{properties:{lastModified:{maximum:s.lastModified,exclusiveMaximum:!0}}});o(await m.next()).toHaveProperty("done",!0);const E=e.discover(t.channels,{properties:{lastModified:{maximum:s.lastModified+.1,exclusiveMaximum:!0}}}),f=await h(E);o(f.name).toEqual(s.name),o(await E.next()).toHaveProperty("done",!0);const y=e.discover(t.channels,{properties:{lastModified:{maximum:s.lastModified}}}),q=await h(y);o(q.name).toEqual(s.name),o(await y.next()).toHaveProperty("done",!0);const g=e.discover(t.channels,{properties:{lastModified:{maximum:s.lastModified-.1}}});o(await g.next()).toHaveProperty("done",!0)})),t("discover schema allowed, as and not as owner",(async()=>{const e=n(),a=l(),t=s(),r=v();r.allowed=[d(),t.actor,d()],await e.put(r,a);const i=e.discover(r.channels,{properties:{allowed:{minItems:3,not:{items:{not:{enum:[t.actor]}}}}}},a),c=await h(i);o(c.value).toEqual(r.value),await o(i.next()).resolves.toHaveProperty("done",!0);const u=e.discover(r.channels,{properties:{allowed:{minItems:3}}},t);await o(u.next()).resolves.toHaveProperty("done",!0);const p=e.discover(r.channels,{properties:{allowed:{not:{items:{not:{enum:[r.channels[0]]}}}}}},t);await o(p.next()).resolves.toHaveProperty("done",!0);const w=e.discover(r.channels,{properties:{allowed:{maxItems:1,not:{items:{not:{enum:[t.actor]}}}}}},t),m=await h(w);o(m.value).toEqual(r.value),await o(w.next()).resolves.toHaveProperty("done",!0)})),t("discover schema channels, as and not as owner",(async()=>{const e=n(),a=l(),t=s(),r=v();r.channels=[d(),d(),d()],await e.put(r,a);const i=e.discover([r.channels[0],r.channels[2]],{properties:{channels:{minItems:3,not:{items:{not:{enum:[r.channels[1]]}}}}}},a),c=await h(i);o(c.value).toEqual(r.value),await o(i.next()).resolves.toHaveProperty("done",!0);const u=e.discover([r.channels[0],r.channels[2]],{properties:{channels:{minItems:3}}},t);await o(u.next()).resolves.toHaveProperty("done",!0);const p=e.discover([r.channels[0],r.channels[2]],{properties:{channels:{not:{items:{not:{enum:[r.channels[1]]}}}}}},t);await o(p.next()).resolves.toHaveProperty("done",!0);const w=e.discover([r.channels[0],r.channels[2]],{properties:{allowed:{maxItems:2,not:{items:{not:{enum:[r.channels[2]]}}}}}},t),m=await h(w);o(m.value).toEqual(r.value),await o(w.next()).resolves.toHaveProperty("done",!0)})),t("discover query for empty allowed",(async()=>{const e=n(),a=l(),t=v(),s={not:{required:["allowed"]}};await e.put(t,a);const r=e.discover(t.channels,s,a),i=await h(r);o(i.value).toEqual(t.value),o(i.allowed).toBeUndefined(),await o(r.next()).resolves.toHaveProperty("done",!0);const c=v();c.allowed=[],await e.put(c,a);const u=e.discover(c.channels,s,a);await o(u.next()).resolves.toHaveProperty("done",!0)})),t("discover query for values",(async()=>{const a=n(),t=l(),s=v();s.value={test:d()},await a.put(s,t);const r=v();r.channels=s.channels,r.value={test:d(),something:d()},await a.put(r,t);const i=v();i.channels=s.channels,i.value={other:d(),something:d()},await a.put(i,t);const c=new Map;for(const t of["test","something","other"]){let o=0;for await(const n of a.discover(s.channels,{properties:{value:{required:[t]}}}))e(!n.error,"result has error"),t in n.value.value&&o++;c.set(t,o)}o(c.get("test")).toBe(2),o(c.get("something")).toBe(2),o(c.get("other")).toBe(1)})),t("discover for deleted content",(async()=>{const e=n(),a=l(),t=v(),s=await e.put(t,a),r=await e.delete(s,a),i=e.discover(t.channels,{}),c=await h(i);o(c.tombstone).toBe(!0),o(c.value).toEqual(t.value),o(c.channels).toEqual(t.channels),o(c.actor).toEqual(a.actor),o(c.lastModified).toEqual(r.lastModified),await o(i.next()).resolves.toHaveProperty("done",!0)})),t("discover for replaced channels",(async()=>{for(let e=0;e<10;e++){const e=n(),a=l(),t=v(),s=await e.put(t,a),r=v(),i=await e.put({...s,...r},a),c=e.discover(t.channels,{}),u=await h(c);await o(c.next()).resolves.toHaveProperty("done",!0);const d=e.discover(r.channels,{}),p=await h(d);await o(d.next()).resolves.toHaveProperty("done",!0),s.lastModified===i.lastModified?(o(u.tombstone||p.tombstone).toBe(!0),o(u.tombstone&&p.tombstone).toBe(!1)):(o(u.tombstone).toBe(!0),o(u.value).toEqual(t.value),o(u.channels).toEqual(t.channels),o(u.lastModified).toEqual(i.lastModified),o(p.tombstone).toBe(!1),o(p.value).toEqual(r.value),o(p.channels).toEqual(r.channels),o(p.lastModified).toEqual(i.lastModified))}})),t("discover for patched allowed",(async()=>{const e=n(),a=l(),t=v(),s=await e.put(t,a);await e.patch({allowed:[{op:"add",path:"",value:[]}]},s,a);const r=e.discover(t.channels,{}),i=await h(r);o(i.tombstone).toBe(!0),o(i.value).toEqual(t.value),o(i.channels).toEqual(t.channels),o(i.allowed).toBeUndefined(),await o(r.next()).resolves.toHaveProperty("done",!0)})),t("put concurrently and discover one",(async()=>{const a=n(),t=l(),s=v();s.name=d();const r=Array(100).fill(0).map((()=>a.put(s,t)));await Promise.all(r);const i=a.discover(s.channels,{});let c=0,u=0;for await(const a of i)e(!a.error,"result has error"),a.value.tombstone?c++:u++;o(c).toBe(99),o(u).toBe(1)}))}))};export{w as graffitiCRUDTests,E as graffitiDiscoverTests,p as graffitiLocationTests,m as graffitiSynchronizeTests};
|
|
1
|
+
import{assert as e,describe as a,it as t,expect as o}from"vitest";import{GraffitiErrorInvalidUri as n,GraffitiErrorNotFound as l,GraffitiErrorForbidden as s,GraffitiErrorInvalidSchema as i,GraffitiErrorSchemaMismatch as r,GraffitiErrorPatchTestFailed as c,GraffitiErrorPatchError as u}from"@graffiti-garden/api";function d(){const e=new Uint8Array(16);return crypto.getRandomValues(e),Array.from(e).map((e=>e.toString(16).padStart(2,"0"))).join("")}function v(){return{value:{[d()]:d()},channels:[d(),d()]}}async function h(a){const t=await a.next();return e(!t.done&&!t.value.error,"result has no value"),t.value.value}const w=e=>{a("URI and location conversion",(()=>{t("location to uri and back",(async()=>{const a=e(),t={name:d(),actor:d(),source:d()},n=a.locationToUri(t),l=a.uriToLocation(n);o(t).toEqual(l)})),t("collision resistance",(async()=>{const a=e(),t={name:d(),actor:d(),source:d()};for(const e of["name","actor","source"]){const n={...t,[e]:d()},l=a.locationToUri(t),s=a.locationToUri(n);o(l).not.toEqual(s)}})),t("random URI should not be a valid location",(async()=>{const a=e();o((()=>a.uriToLocation(""))).toThrow(n)}))}))},p=(e,n,h)=>{a("CRUD",(()=>{t("put, get, delete",(async()=>{const a=e(),t=n(),s={something:"hello, world~ c:"},i=[d(),d()],r=await a.put({value:s,channels:i},t);o(r.value).toEqual({}),o(r.channels).toEqual([]),o(r.allowed).toBeUndefined(),o(r.actor).toEqual(t.actor);const c=await a.get(r,{});o(c.value).toEqual(s),o(c.channels).toEqual([]),o(c.allowed).toBeUndefined(),o(c.name).toEqual(r.name),o(c.actor).toEqual(r.actor),o(c.source).toEqual(r.source),o(c.lastModified).toEqual(r.lastModified);const u={something:"goodbye, world~ :c"},v=await a.put({...r,value:u,channels:[]},t);o(v.value).toEqual(s),o(v.tombstone).toEqual(!0),o(v.name).toEqual(r.name),o(v.actor).toEqual(r.actor),o(v.source).toEqual(r.source),o(v.lastModified).toBeGreaterThan(c.lastModified);const h=await a.get(r,{});o(h.value).toEqual(u),o(h.lastModified).toEqual(v.lastModified),o(h.tombstone).toEqual(!1);const w=await a.delete(h,t);o(w.tombstone).toEqual(!0),o(w.value).toEqual(u),o(w.lastModified).toBeGreaterThan(v.lastModified),await o(a.get(h,{})).rejects.toThrow(l)})),t("put, get, delete with wrong actor",(async()=>{const a=e(),t=n(),l=h();await o(a.put({value:{},channels:[],actor:l.actor},t)).rejects.toThrow(s),await o(a.delete({name:"asdf",source:"asdf",actor:l.actor},t)).rejects.toThrow(s),await o(a.patch({},{name:"asdf",source:"asdf",actor:l.actor},t)).rejects.toThrow(s)})),t("put and get with schema",(async()=>{const a=e(),t=n(),l={something:"hello",another:42},s=await a.put({value:l,channels:[]},t),i=await a.get(s,{properties:{value:{properties:{something:{type:"string"},another:{type:"integer"}}}}});o(i.value.something).toEqual(l.something),o(i.value.another).toEqual(l.another)})),t("put and get with invalid schema",(async()=>{const a=e(),t=n(),l=await a.put({value:{},channels:[]},t);await o(a.get(l,{properties:{value:{type:"asdf"}}})).rejects.toThrow(i)})),t("put and get with wrong schema",(async()=>{const a=e(),t=n(),l=await a.put({value:{hello:"world"},channels:[]},t);await o(a.get(l,{properties:{value:{properties:{hello:{type:"number"}}}}})).rejects.toThrow(r)})),t("put and get with empty access control",(async()=>{const a=e(),t=n(),l=h(),s={um:"hi"},i=[d()],r=[d()],c=await a.put({value:s,allowed:i,channels:r},t),u=await a.get(c,{},t);o(u.value).toEqual(s),o(u.allowed).toEqual(i),o(u.channels).toEqual(r),await o(a.get(c,{})).rejects.toThrow(),await o(a.get(c,{},l)).rejects.toThrow()})),t("put and get with specific access control",(async()=>{const a=e(),t=n(),l=h(),s={um:"hi"},i=[d(),l.actor,d()],r=[d()],c=await a.put({value:s,allowed:i,channels:r},t),u=await a.get(c,{},t);o(u.value).toEqual(s),o(u.allowed).toEqual(i),o(u.channels).toEqual(r),await o(a.get(c,{})).rejects.toThrow();const v=await a.get(c,{},l);o(v.value).toEqual(s),o(v.allowed).toEqual([l.actor]),o(v.channels).toEqual([])})),t("patch value",(async()=>{const a=e(),t=n(),l={something:"hello, world~ c:"},s=await a.put({value:l,channels:[]},t),i=await a.patch({value:[{op:"replace",path:"/something",value:"goodbye, world~ :c"}]},s,t);o(i.value).toEqual(l),o(i.tombstone).toBe(!0);const r=await a.get(s,{});o(r.value).toEqual({something:"goodbye, world~ :c"}),o(i.lastModified).toBe(r.lastModified),await a.delete(s,t)})),t("deep patch",(async()=>{const a=e(),t=n(),l={something:{another:{somethingElse:"hello"}}},s=await a.put({value:l,channels:[]},t),i=await a.patch({value:[{op:"replace",path:"/something/another/somethingElse",value:"goodbye"}]},s,t),r=await a.get(s,{});o(i.value).toEqual(l),o(r.value).toEqual({something:{another:{somethingElse:"goodbye"}}})})),t("patch channels",(async()=>{const a=e(),t=n(),l=[d()],s=[d()],i=await a.put({value:{},channels:l},t),r={channels:[{op:"replace",path:"/0",value:s[0]}]},c=await a.patch(r,i,t);o(c.channels).toEqual(l);const u=await a.get(i,{},t);o(u.channels).toEqual(s),await a.delete(i,t)})),t("patch 'increment' with test",(async()=>{const a=e(),t=n(),l=await a.put({value:{counter:1},channels:[]},t),s=await a.patch({value:[{op:"test",path:"/counter",value:1},{op:"replace",path:"/counter",value:2}]},l,t);o(s.value).toEqual({counter:1});const i=await a.get(s,{properties:{value:{properties:{counter:{type:"integer"}}}}});o(i.value.counter).toEqual(2),await o(a.patch({value:[{op:"test",path:"/counter",value:1},{op:"replace",path:"/counter",value:3}]},l,t)).rejects.toThrow(c)})),t("invalid patch",(async()=>{const a=e(),t=n(),l=v(),s=await a.put(l,t);await o(a.patch({value:[{op:"add",path:"/root",value:[]},{op:"add",path:"/root/2",value:2}]},s,t)).rejects.toThrow(u)})),t("patch channels to be wrong",(async()=>{const a=e(),t=n(),l=v();l.allowed=[d()];const s=await a.put(l,t),i=[{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(const e of i)await o(a.patch(e,s,t)).rejects.toThrow(u);const r=await a.get(s,{},t);o(r.value).toEqual(l.value),o(r.channels).toEqual(l.channels),o(r.allowed).toEqual(l.allowed),o(r.lastModified).toEqual(s.lastModified)}))}))},m=(e,n,l)=>{a("synchronize",(()=>{t("get",(async()=>{const a=e(),t=n(),l=v(),s=l.channels.slice(1),i=await a.put(l,t),r=e(),c=r.synchronize(s,{}).next(),u=await r.get(i,{},t),d=(await c).value;if(!d||d.error)throw new Error("Error in synchronize");o(d.value.value).toEqual(l.value),o(d.value.channels).toEqual(s),o(d.value.tombstone).toBe(!1),o(d.value.lastModified).toEqual(u.lastModified)})),t("put",(async()=>{const a=e(),t=n(),l=d(),s=d(),i=d(),r={hello:"world"},c=[l,i],u=await a.put({value:r,channels:c},t),v=a.synchronize([l],{}).next(),h=a.synchronize([s],{}).next(),w=a.synchronize([i],{}).next(),p={goodbye:"world"},m=[s,i];await a.put({...u,value:p,channels:m},t);const E=(await v).value,q=(await h).value,f=(await w).value;if(!E||E.error||!q||q.error||!f||f.error)throw new Error("Error in synchronize");o(E.value.value).toEqual(r),o(E.value.channels).toEqual([l]),o(E.value.tombstone).toBe(!0),o(q.value.value).toEqual(p),o(q.value.channels).toEqual([s]),o(q.value.tombstone).toBe(!1),o(f.value.value).toEqual(p),o(f.value.channels).toEqual([i]),o(f.value.tombstone).toBe(!1),o(E.value.lastModified).toEqual(q.value.lastModified),o(f.value.lastModified).toEqual(q.value.lastModified)})),t("patch",(async()=>{const a=e(),t=n(),l=d(),s=d(),i=d(),r={hello:"world"},c=[l,i],u=await a.put({value:r,channels:c},t),v=a.synchronize([l],{}).next(),h=a.synchronize([s],{}).next(),w=a.synchronize([i],{}).next();await a.patch({value:[{op:"add",path:"/something",value:"new value"}],channels:[{op:"add",path:"/-",value:s},{op:"remove",path:`/${c.indexOf(l)}`}]},u,t);const p=(await v).value,m=(await h).value,E=(await w).value;if(!p||p.error||!m||m.error||!E||E.error)throw new Error("Error in synchronize");const q={...r,something:"new value"};o(p.value.value).toEqual(r),o(p.value.channels).toEqual([l]),o(p.value.tombstone).toBe(!0),o(m.value.value).toEqual(q),o(m.value.channels).toEqual([s]),o(m.value.tombstone).toBe(!1),o(E.value.value).toEqual(q),o(E.value.channels).toEqual([i]),o(E.value.tombstone).toBe(!1),o(p.value.lastModified).toEqual(m.value.lastModified),o(E.value.lastModified).toEqual(m.value.lastModified)})),t("delete",(async()=>{const a=e(),t=n(),l=[d(),d(),d()],s={hello:"world"},i=[d(),...l.slice(1)],r=await a.put({value:s,channels:i},t),c=a.synchronize(l,{}).next();a.delete(r,t);const u=(await c).value;if(!u||u.error)throw new Error("Error in synchronize");o(u.value.tombstone).toBe(!0),o(u.value.value).toEqual(s),o(u.value.channels).toEqual(l.filter((e=>i.includes(e))))})),t("not allowed",(async()=>{const a=e(),t=n(),s=l(),i=[d(),d(),d()],r=i.slice(1),c=a.synchronize(r,{},t).next(),u=a.synchronize(r,{},s).next(),v=a.synchronize(r,{}).next(),h={hello:"world"},w=[d(),s.actor];await a.put({value:h,channels:i,allowed:w},t),await o(Promise.race([v,new Promise(((e,a)=>setTimeout(a,100,"Timeout")))])).rejects.toThrow("Timeout");const p=(await c).value,m=(await u).value;if(!p||p.error||!m||m.error)throw new Error("Error in synchronize");o(p.value.value).toEqual(h),o(p.value.allowed).toEqual(w),o(p.value.channels).toEqual(i),o(m.value.value).toEqual(h),o(m.value.allowed).toEqual([s.actor]),o(m.value.channels).toEqual(r)}))}))},E=(n,l,s)=>{a("discover",(()=>{t("discover nothing",(async()=>{const e=n().discover([],{});o(await e.next()).toHaveProperty("done",!0)})),t("discover single",(async()=>{const e=n(),a=l(),t=v(),s=await e.put(t,a),i=[d(),t.channels[0]],r=e.discover(i,{}),c=await h(r);o(c.value).toEqual(t.value),o(c.channels).toEqual([t.channels[0]]),o(c.allowed).toBeUndefined(),o(c.actor).toEqual(a.actor),o(c.tombstone).toBe(!1),o(c.lastModified).toEqual(s.lastModified);const u=await r.next();o(u.done).toBe(!0)})),t("discover wrong channel",(async()=>{const e=n(),a=l(),t=v();await e.put(t,a);const s=e.discover([d()],{});await o(s.next()).resolves.toHaveProperty("done",!0)})),t("discover not allowed",(async()=>{const e=n(),a=l(),t=s(),i=v();i.allowed=[d(),d()];const r=await e.put(i,a),c=e.discover(i.channels,{},a),u=await h(c);o(u.value).toEqual(i.value),o(u.channels).toEqual(i.channels),o(u.allowed).toEqual(i.allowed),o(u.actor).toEqual(a.actor),o(u.tombstone).toBe(!1),o(u.lastModified).toEqual(r.lastModified);const w=e.discover(i.channels,{},t);o(await w.next()).toHaveProperty("done",!0);const p=e.discover(i.channels,{});o(await p.next()).toHaveProperty("done",!0)})),t("discover allowed",(async()=>{const e=n(),a=l(),t=s(),i=v();i.allowed=[d(),t.actor,d()];const r=await e.put(i,a),c=e.discover(i.channels,{},t),u=await h(c);o(u.value).toEqual(i.value),o(u.allowed).toEqual([t.actor]),o(u.channels).toEqual(i.channels),o(u.actor).toEqual(a.actor),o(u.tombstone).toBe(!1),o(u.lastModified).toEqual(r.lastModified)}));for(const e of["name","actor","lastModified"])t(`discover for ${e}`,(async()=>{const a=n(),t=l(),i=s(),r=v(),c=await a.put(r,t),u=v();u.channels=r.channels,await new Promise((e=>setTimeout(e,20)));const d=await a.put(u,i),w=a.discover(r.channels,{properties:{[e]:{enum:[c[e]]}}}),p=await h(w);o(p.name).toEqual(c.name),o(p.name).not.toEqual(d.name),o(p.value).toEqual(r.value),await o(w.next()).resolves.toHaveProperty("done",!0)}));t("discover with lastModified range",(async()=>{const e=n(),a=l(),t=v(),s=await e.put(t,a);await new Promise((e=>setTimeout(e,20)));const i=await e.put(t,a);o(s.name).not.toEqual(i.name),o(s.lastModified).toBeLessThan(i.lastModified);const r=e.discover([t.channels[0]],{properties:{lastModified:{minimum:i.lastModified,exclusiveMinimum:!0}}});o(await r.next()).toHaveProperty("done",!0);const c=e.discover([t.channels[0]],{properties:{lastModified:{minimum:i.lastModified-.1,exclusiveMinimum:!0}}}),u=await h(c);o(u.name).toEqual(i.name),o(await c.next()).toHaveProperty("done",!0);const d=e.discover(t.channels,{properties:{value:{},lastModified:{minimum:i.lastModified}}}),w=await h(d);o(w.name).toEqual(i.name),o(await d.next()).toHaveProperty("done",!0);const p=e.discover(t.channels,{properties:{lastModified:{minimum:i.lastModified+.1}}});o(await p.next()).toHaveProperty("done",!0);const m=e.discover(t.channels,{properties:{lastModified:{maximum:s.lastModified,exclusiveMaximum:!0}}});o(await m.next()).toHaveProperty("done",!0);const E=e.discover(t.channels,{properties:{lastModified:{maximum:s.lastModified+.1,exclusiveMaximum:!0}}}),q=await h(E);o(q.name).toEqual(s.name),o(await E.next()).toHaveProperty("done",!0);const f=e.discover(t.channels,{properties:{lastModified:{maximum:s.lastModified}}}),y=await h(f);o(y.name).toEqual(s.name),o(await f.next()).toHaveProperty("done",!0);const g=e.discover(t.channels,{properties:{lastModified:{maximum:s.lastModified-.1}}});o(await g.next()).toHaveProperty("done",!0)})),t("discover schema allowed, as and not as owner",(async()=>{const e=n(),a=l(),t=s(),i=v();i.allowed=[d(),t.actor,d()],await e.put(i,a);const r=e.discover(i.channels,{properties:{allowed:{minItems:3,not:{items:{not:{enum:[t.actor]}}}}}},a),c=await h(r);o(c.value).toEqual(i.value),await o(r.next()).resolves.toHaveProperty("done",!0);const u=e.discover(i.channels,{properties:{allowed:{minItems:3}}},t);await o(u.next()).resolves.toHaveProperty("done",!0);const w=e.discover(i.channels,{properties:{allowed:{not:{items:{not:{enum:[i.channels[0]]}}}}}},t);await o(w.next()).resolves.toHaveProperty("done",!0);const p=e.discover(i.channels,{properties:{allowed:{maxItems:1,not:{items:{not:{enum:[t.actor]}}}}}},t),m=await h(p);o(m.value).toEqual(i.value),await o(p.next()).resolves.toHaveProperty("done",!0)})),t("discover schema channels, as and not as owner",(async()=>{const e=n(),a=l(),t=s(),i=v();i.channels=[d(),d(),d()],await e.put(i,a);const r=e.discover([i.channels[0],i.channels[2]],{properties:{channels:{minItems:3,not:{items:{not:{enum:[i.channels[1]]}}}}}},a),c=await h(r);o(c.value).toEqual(i.value),await o(r.next()).resolves.toHaveProperty("done",!0);const u=e.discover([i.channels[0],i.channels[2]],{properties:{channels:{minItems:3}}},t);await o(u.next()).resolves.toHaveProperty("done",!0);const w=e.discover([i.channels[0],i.channels[2]],{properties:{channels:{not:{items:{not:{enum:[i.channels[1]]}}}}}},t);await o(w.next()).resolves.toHaveProperty("done",!0);const p=e.discover([i.channels[0],i.channels[2]],{properties:{allowed:{maxItems:2,not:{items:{not:{enum:[i.channels[2]]}}}}}},t),m=await h(p);o(m.value).toEqual(i.value),await o(p.next()).resolves.toHaveProperty("done",!0)})),t("discover query for empty allowed",(async()=>{const e=n(),a=l(),t=v(),s={not:{required:["allowed"]}};await e.put(t,a);const i=e.discover(t.channels,s,a),r=await h(i);o(r.value).toEqual(t.value),o(r.allowed).toBeUndefined(),await o(i.next()).resolves.toHaveProperty("done",!0);const c=v();c.allowed=[],await e.put(c,a);const u=e.discover(c.channels,s,a);await o(u.next()).resolves.toHaveProperty("done",!0)})),t("discover query for values",(async()=>{const a=n(),t=l(),s=v();s.value={test:d()},await a.put(s,t);const i=v();i.channels=s.channels,i.value={test:d(),something:d()},await a.put(i,t);const r=v();r.channels=s.channels,r.value={other:d(),something:d()},await a.put(r,t);const c=new Map;for(const t of["test","something","other"]){let o=0;for await(const n of a.discover(s.channels,{properties:{value:{required:[t]}}}))e(!n.error,"result has error"),t in n.value.value&&o++;c.set(t,o)}o(c.get("test")).toBe(2),o(c.get("something")).toBe(2),o(c.get("other")).toBe(1)})),t("discover for deleted content",(async()=>{const e=n(),a=l(),t=v(),s=await e.put(t,a),i=await e.delete(s,a),r=e.discover(t.channels,{}),c=await h(r);o(c.tombstone).toBe(!0),o(c.value).toEqual(t.value),o(c.channels).toEqual(t.channels),o(c.actor).toEqual(a.actor),o(c.lastModified).toEqual(i.lastModified),await o(r.next()).resolves.toHaveProperty("done",!0)})),t("discover for replaced channels",(async()=>{for(let e=0;e<10;e++){const e=n(),a=l(),t=v(),s=await e.put(t,a),i=v(),r=await e.put({...s,...i},a),c=e.discover(t.channels,{}),u=await h(c);await o(c.next()).resolves.toHaveProperty("done",!0);const d=e.discover(i.channels,{}),w=await h(d);await o(d.next()).resolves.toHaveProperty("done",!0),s.lastModified===r.lastModified?(o(u.tombstone||w.tombstone).toBe(!0),o(u.tombstone&&w.tombstone).toBe(!1)):(o(u.tombstone).toBe(!0),o(u.value).toEqual(t.value),o(u.channels).toEqual(t.channels),o(u.lastModified).toEqual(r.lastModified),o(w.tombstone).toBe(!1),o(w.value).toEqual(i.value),o(w.channels).toEqual(i.channels),o(w.lastModified).toEqual(r.lastModified))}})),t("discover for patched allowed",(async()=>{const e=n(),a=l(),t=v(),s=await e.put(t,a);await e.patch({allowed:[{op:"add",path:"",value:[]}]},s,a);const i=e.discover(t.channels,{}),r=await h(i);o(r.tombstone).toBe(!0),o(r.value).toEqual(t.value),o(r.channels).toEqual(t.channels),o(r.allowed).toBeUndefined(),await o(i.next()).resolves.toHaveProperty("done",!0)})),t("put concurrently and discover one",(async()=>{const a=n(),t=l(),s=v();s.name=d();const i=Array(100).fill(0).map((()=>a.put(s,t)));await Promise.all(i);const r=a.discover(s.channels,{});let c=0,u=0;for await(const a of r)e(!a.error,"result has error"),a.value.tombstone?c++:u++;o(c).toBe(99),o(u).toBe(1)}))}))};export{p as graffitiCRUDTests,E as graffitiDiscoverTests,w as graffitiLocationTests,m as graffitiSynchronizeTests};
|
|
2
2
|
//# sourceMappingURL=index.js.map
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import { type GraffitiFactory, type GraffitiSession } from "
|
|
1
|
+
import { type GraffitiFactory, type GraffitiSession } from "@graffiti-garden/api";
|
|
2
2
|
export declare const graffitiCRUDTests: (useGraffiti: GraffitiFactory, useSession1: () => GraffitiSession, useSession2: () => GraffitiSession) => void;
|
|
3
3
|
//# sourceMappingURL=crud.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"crud.d.ts","sourceRoot":"","sources":["../../../tests/src/crud.ts"],"names":[],"mappings":"AACA,OAAO,EACL,KAAK,eAAe,EACpB,KAAK,eAAe,EAQrB,MAAM,sBAAsB,CAAC;AAG9B,eAAO,MAAM,iBAAiB,gBACf,eAAe,eACf,MAAM,eAAe,eACrB,MAAM,eAAe,SAucnC,CAAC"}
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import type { GraffitiFactory, GraffitiSession } from "@graffiti-garden/api";
|
|
2
2
|
export declare const graffitiDiscoverTests: (useGraffiti: GraffitiFactory, useSession1: () => GraffitiSession, useSession2: () => GraffitiSession) => void;
|
|
3
3
|
//# sourceMappingURL=discover.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"discover.d.ts","sourceRoot":"","sources":["../../../tests/src/discover.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,eAAe,EACf,eAAe,EAEhB,MAAM,sBAAsB,CAAC;AAG9B,eAAO,MAAM,qBAAqB,gBACnB,eAAe,eACf,MAAM,eAAe,eACrB,MAAM,eAAe,SA0kBnC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../tests/src/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC;AAC3B,cAAc,QAAQ,CAAC;AACvB,cAAc,eAAe,CAAC;AAC9B,cAAc,YAAY,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"location.d.ts","sourceRoot":"","sources":["../../../tests/src/location.ts"],"names":[],"mappings":"AACA,OAAO,EAEL,KAAK,eAAe,EACrB,MAAM,sBAAsB,CAAC;AAG9B,eAAO,MAAM,qBAAqB,gBAAiB,eAAe,SAkCjE,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"crud.d.ts","sourceRoot":"","sources":["../../../../tests/src/crud.ts"],"names":[],"mappings":"AACA,OAAO,EACL,KAAK,eAAe,EACpB,KAAK,eAAe,EAQrB,MAAM,sBAAsB,CAAC;AAG9B,eAAO,MAAM,iBAAiB,gBACf,eAAe,eACf,MAAM,eAAe,eACrB,MAAM,eAAe,SAucnC,CAAC"}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import type { GraffitiFactory, GraffitiSession } from "@graffiti-garden/api";
|
|
2
|
+
export declare const graffitiDiscoverTests: (useGraffiti: GraffitiFactory, useSession1: () => GraffitiSession, useSession2: () => GraffitiSession) => void;
|
|
3
|
+
//# sourceMappingURL=discover.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"discover.d.ts","sourceRoot":"","sources":["../../../../tests/src/discover.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,eAAe,EACf,eAAe,EAEhB,MAAM,sBAAsB,CAAC;AAG9B,eAAO,MAAM,qBAAqB,gBACnB,eAAe,eACf,MAAM,eAAe,eACrB,MAAM,eAAe,SA0kBnC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../tests/src/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC;AAC3B,cAAc,QAAQ,CAAC;AACvB,cAAc,eAAe,CAAC;AAC9B,cAAc,YAAY,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"location.d.ts","sourceRoot":"","sources":["../../../../tests/src/location.ts"],"names":[],"mappings":"AACA,OAAO,EAEL,KAAK,eAAe,EACrB,MAAM,sBAAsB,CAAC;AAG9B,eAAO,MAAM,qBAAqB,gBAAiB,eAAe,SAkCjE,CAAC"}
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import type { GraffitiFactory, GraffitiSession } from "@graffiti-garden/api";
|
|
2
2
|
export declare const graffitiSynchronizeTests: (useGraffiti: GraffitiFactory, useSession1: () => GraffitiSession, useSession2: () => GraffitiSession) => void;
|
|
3
3
|
//# sourceMappingURL=synchronize.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"synchronize.d.ts","sourceRoot":"","sources":["../../../../tests/src/synchronize.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAG7E,eAAO,MAAM,wBAAwB,gBACtB,eAAe,eACf,MAAM,eAAe,eACrB,MAAM,eAAe,SA2PnC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../../tests/src/utils.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,iBAAiB,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAE9E,wBAAgB,YAAY,IAAI,MAAM,CAMrC;AAED,wBAAgB,WAAW;;EAI1B;AAED,wBAAgB,eAAe,IAAI,iBAAiB,CAAC,EAAE,CAAC,CAKvD;AAED,wBAAsB,eAAe,CAAC,CAAC,EAAE,CAAC,EAAE,QAAQ,EAAE,cAAc,CAAC,CAAC,EAAE,CAAC,CAAC,cAIzE"}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import type { GraffitiFactory, GraffitiSession } from "@graffiti-garden/api";
|
|
2
|
+
export declare const graffitiSynchronizeTests: (useGraffiti: GraffitiFactory, useSession1: () => GraffitiSession, useSession2: () => GraffitiSession) => void;
|
|
3
|
+
//# sourceMappingURL=synchronize.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"synchronize.d.ts","sourceRoot":"","sources":["../../../tests/src/synchronize.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAG7E,eAAO,MAAM,wBAAwB,gBACtB,eAAe,eACf,MAAM,eAAe,eACrB,MAAM,eAAe,SA2PnC,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { GraffitiPutObject, GraffitiStream } from "@graffiti-garden/api";
|
|
2
|
+
export declare function randomString(): string;
|
|
3
|
+
export declare function randomValue(): {
|
|
4
|
+
[x: string]: string;
|
|
5
|
+
};
|
|
6
|
+
export declare function randomPutObject(): GraffitiPutObject<{}>;
|
|
7
|
+
export declare function nextStreamValue<S, T>(iterator: GraffitiStream<S, T>): Promise<S>;
|
|
8
|
+
//# sourceMappingURL=utils.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../tests/src/utils.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,iBAAiB,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAE9E,wBAAgB,YAAY,IAAI,MAAM,CAMrC;AAED,wBAAgB,WAAW;;EAI1B;AAED,wBAAgB,eAAe,IAAI,iBAAiB,CAAC,EAAE,CAAC,CAKvD;AAED,wBAAsB,eAAe,CAAC,CAAC,EAAE,CAAC,EAAE,QAAQ,EAAE,cAAc,CAAC,CAAC,EAAE,CAAC,CAAC,cAIzE"}
|
package/package.json
CHANGED
|
@@ -1,32 +1,25 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@graffiti-garden/api",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.6",
|
|
4
4
|
"description": "The heart of Graffiti",
|
|
5
|
-
"types": "./dist/
|
|
5
|
+
"types": "./dist/src/index.d.ts",
|
|
6
6
|
"module": "./dist/index.js",
|
|
7
7
|
"main": "./dist/index.cjs.js",
|
|
8
8
|
"exports": {
|
|
9
9
|
".": {
|
|
10
10
|
"import": {
|
|
11
|
-
"types": "./dist/
|
|
11
|
+
"types": "./dist/src/index.d.ts",
|
|
12
12
|
"node": "./dist/index.cjs.js",
|
|
13
13
|
"default": "./dist/index.js"
|
|
14
14
|
},
|
|
15
15
|
"require": {
|
|
16
|
-
"types": "./dist/
|
|
16
|
+
"types": "./dist/src/index.d.ts",
|
|
17
17
|
"default": "./dist/index.cjs.js"
|
|
18
18
|
}
|
|
19
19
|
},
|
|
20
20
|
"./tests": {
|
|
21
|
-
"
|
|
22
|
-
|
|
23
|
-
"node": "./dist/tests/index.cjs.js",
|
|
24
|
-
"default": "./dist/tests/index.js"
|
|
25
|
-
},
|
|
26
|
-
"require": {
|
|
27
|
-
"types": "./dist/types/tests/index.d.ts",
|
|
28
|
-
"default": "./dist/tests/index.cjs.js"
|
|
29
|
-
}
|
|
21
|
+
"types": "./dist/tests/src/index.d.ts",
|
|
22
|
+
"default": "./dist/tests/index.js"
|
|
30
23
|
}
|
|
31
24
|
},
|
|
32
25
|
"files": [
|
|
@@ -40,7 +33,9 @@
|
|
|
40
33
|
"license": "GPL-3.0-or-later",
|
|
41
34
|
"scripts": {
|
|
42
35
|
"docs": "typedoc --options typedoc.json",
|
|
43
|
-
"build": "rollup -c rollup.config.ts --configPlugin rollup-plugin-typescript2",
|
|
36
|
+
"build-api": "rollup -c rollup.config.ts --configPlugin rollup-plugin-typescript2",
|
|
37
|
+
"build-tests": "cd tests && rollup -c rollup.config.ts --configPlugin rollup-plugin-typescript2",
|
|
38
|
+
"build": "npm run build-api && npm run build-tests",
|
|
44
39
|
"prepublishOnly": "npm install && npm run build"
|
|
45
40
|
},
|
|
46
41
|
"repository": {
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import typescript from "rollup-plugin-typescript2";
|
|
2
|
+
import terser from "@rollup/plugin-terser";
|
|
3
|
+
|
|
4
|
+
export default {
|
|
5
|
+
input: "src/index.ts",
|
|
6
|
+
output: {
|
|
7
|
+
file: "../dist/tests/index.js",
|
|
8
|
+
format: "es",
|
|
9
|
+
sourcemap: true,
|
|
10
|
+
},
|
|
11
|
+
external: ["vitest", "@graffiti-garden/api"],
|
|
12
|
+
plugins: [
|
|
13
|
+
typescript({
|
|
14
|
+
tsconfig: "tsconfig.json",
|
|
15
|
+
useTsconfigDeclarationDir: true,
|
|
16
|
+
}),
|
|
17
|
+
terser(),
|
|
18
|
+
],
|
|
19
|
+
};
|
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
import { it, expect, describe, assert } from "vitest";
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
} from "../src/index";
|
|
2
|
+
import type {
|
|
3
|
+
GraffitiFactory,
|
|
4
|
+
GraffitiSession,
|
|
5
|
+
JSONSchema4,
|
|
6
|
+
} from "@graffiti-garden/api";
|
|
8
7
|
import { randomString, nextStreamValue, randomPutObject } from "./utils";
|
|
9
8
|
|
|
10
9
|
export const graffitiDiscoverTests = (
|
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
import { it, expect, describe } from "vitest";
|
|
2
|
-
import {
|
|
2
|
+
import {
|
|
3
|
+
GraffitiErrorInvalidUri,
|
|
4
|
+
type GraffitiFactory,
|
|
5
|
+
} from "@graffiti-garden/api";
|
|
3
6
|
import { randomString } from "./utils";
|
|
4
7
|
|
|
5
8
|
export const graffitiLocationTests = (useGraffiti: GraffitiFactory) => {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { it, expect, describe } from "vitest";
|
|
2
|
-
import {
|
|
2
|
+
import type { GraffitiFactory, GraffitiSession } from "@graffiti-garden/api";
|
|
3
3
|
import { randomPutObject, randomString } from "./utils";
|
|
4
4
|
|
|
5
5
|
export const graffitiSynchronizeTests = (
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"target": "esnext",
|
|
4
|
+
"module": "esnext",
|
|
5
|
+
"moduleResolution": "bundler",
|
|
6
|
+
"strict": true,
|
|
7
|
+
"esModuleInterop": true,
|
|
8
|
+
"resolveJsonModule": true,
|
|
9
|
+
"verbatimModuleSyntax": true,
|
|
10
|
+
"declaration": true,
|
|
11
|
+
"declarationMap": true,
|
|
12
|
+
"declarationDir": "../dist/tests",
|
|
13
|
+
"rootDir": "."
|
|
14
|
+
},
|
|
15
|
+
"include": ["src"]
|
|
16
|
+
}
|
package/dist/tests/index.cjs.js
DELETED
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
"use strict";var e=require("vitest");class t extends Error{constructor(e){super(e),this.name="GraffitiErrorForbidden",Object.setPrototypeOf(this,t.prototype)}}class a extends Error{constructor(e){super(e),this.name="GraffitiErrorNotFound",Object.setPrototypeOf(this,a.prototype)}}class o extends Error{constructor(e){super(e),this.name="GraffitiErrorInvalidSchema",Object.setPrototypeOf(this,o.prototype)}}class n extends Error{constructor(e){super(e),this.name="GraffitiErrorSchemaMismatch",Object.setPrototypeOf(this,n.prototype)}}class c extends Error{constructor(e){super(e),this.name="GraffitiErrorPatchTestFailed",Object.setPrototypeOf(this,c.prototype)}}class l extends Error{constructor(e){super(e),this.name="GraffitiErrorPatchError",Object.setPrototypeOf(this,l.prototype)}}class s extends Error{constructor(e){super(e),this.name="GraffitiErrorInvalidUri",Object.setPrototypeOf(this,s.prototype)}}function r(){const e=new Uint8Array(16);return crypto.getRandomValues(e),Array.from(e).map((e=>e.toString(16).padStart(2,"0"))).join("")}function i(){return{value:{[r()]:r()},channels:[r(),r()]}}async function p(t){const a=await t.next();return e.assert(!a.done&&!a.value.error,"result has no value"),a.value.value}exports.graffitiCRUDTests=(s,p,u)=>{e.describe("CRUD",(()=>{e.it("put, get, delete",(async()=>{const t=s(),o=p(),n={something:"hello, world~ c:"},c=[r(),r()],l=await t.put({value:n,channels:c},o);e.expect(l.value).toEqual({}),e.expect(l.channels).toEqual([]),e.expect(l.allowed).toBeUndefined(),e.expect(l.actor).toEqual(o.actor);const i=await t.get(l,{});e.expect(i.value).toEqual(n),e.expect(i.channels).toEqual([]),e.expect(i.allowed).toBeUndefined(),e.expect(i.name).toEqual(l.name),e.expect(i.actor).toEqual(l.actor),e.expect(i.source).toEqual(l.source),e.expect(i.lastModified).toEqual(l.lastModified);const u={something:"goodbye, world~ :c"},d=await t.put({...l,value:u,channels:[]},o);e.expect(d.value).toEqual(n),e.expect(d.tombstone).toEqual(!0),e.expect(d.name).toEqual(l.name),e.expect(d.actor).toEqual(l.actor),e.expect(d.source).toEqual(l.source),e.expect(d.lastModified).toBeGreaterThan(i.lastModified);const v=await t.get(l,{});e.expect(v.value).toEqual(u),e.expect(v.lastModified).toEqual(d.lastModified),e.expect(v.tombstone).toEqual(!1);const h=await t.delete(v,o);e.expect(h.tombstone).toEqual(!0),e.expect(h.value).toEqual(u),e.expect(h.lastModified).toBeGreaterThan(d.lastModified),await e.expect(t.get(v,{})).rejects.toThrow(a)})),e.it("put, get, delete with wrong actor",(async()=>{const a=s(),o=p(),n=u();await e.expect(a.put({value:{},channels:[],actor:n.actor},o)).rejects.toThrow(t),await e.expect(a.delete({name:"asdf",source:"asdf",actor:n.actor},o)).rejects.toThrow(t),await e.expect(a.patch({},{name:"asdf",source:"asdf",actor:n.actor},o)).rejects.toThrow(t)})),e.it("put and get with schema",(async()=>{const t=s(),a=p(),o={something:"hello",another:42},n=await t.put({value:o,channels:[]},a),c=await t.get(n,{properties:{value:{properties:{something:{type:"string"},another:{type:"integer"}}}}});e.expect(c.value.something).toEqual(o.something),e.expect(c.value.another).toEqual(o.another)})),e.it("put and get with invalid schema",(async()=>{const t=s(),a=p(),n=await t.put({value:{},channels:[]},a);await e.expect(t.get(n,{properties:{value:{type:"asdf"}}})).rejects.toThrow(o)})),e.it("put and get with wrong schema",(async()=>{const t=s(),a=p(),o=await t.put({value:{hello:"world"},channels:[]},a);await e.expect(t.get(o,{properties:{value:{properties:{hello:{type:"number"}}}}})).rejects.toThrow(n)})),e.it("put and get with empty access control",(async()=>{const t=s(),a=p(),o=u(),n={um:"hi"},c=[r()],l=[r()],i=await t.put({value:n,allowed:c,channels:l},a),d=await t.get(i,{},a);e.expect(d.value).toEqual(n),e.expect(d.allowed).toEqual(c),e.expect(d.channels).toEqual(l),await e.expect(t.get(i,{})).rejects.toThrow(),await e.expect(t.get(i,{},o)).rejects.toThrow()})),e.it("put and get with specific access control",(async()=>{const t=s(),a=p(),o=u(),n={um:"hi"},c=[r(),o.actor,r()],l=[r()],i=await t.put({value:n,allowed:c,channels:l},a),d=await t.get(i,{},a);e.expect(d.value).toEqual(n),e.expect(d.allowed).toEqual(c),e.expect(d.channels).toEqual(l),await e.expect(t.get(i,{})).rejects.toThrow();const v=await t.get(i,{},o);e.expect(v.value).toEqual(n),e.expect(v.allowed).toEqual([o.actor]),e.expect(v.channels).toEqual([])})),e.it("patch value",(async()=>{const t=s(),a=p(),o={something:"hello, world~ c:"},n=await t.put({value:o,channels:[]},a),c=await t.patch({value:[{op:"replace",path:"/something",value:"goodbye, world~ :c"}]},n,a);e.expect(c.value).toEqual(o),e.expect(c.tombstone).toBe(!0);const l=await t.get(n,{});e.expect(l.value).toEqual({something:"goodbye, world~ :c"}),e.expect(c.lastModified).toBe(l.lastModified),await t.delete(n,a)})),e.it("deep patch",(async()=>{const t=s(),a=p(),o={something:{another:{somethingElse:"hello"}}},n=await t.put({value:o,channels:[]},a),c=await t.patch({value:[{op:"replace",path:"/something/another/somethingElse",value:"goodbye"}]},n,a),l=await t.get(n,{});e.expect(c.value).toEqual(o),e.expect(l.value).toEqual({something:{another:{somethingElse:"goodbye"}}})})),e.it("patch channels",(async()=>{const t=s(),a=p(),o=[r()],n=[r()],c=await t.put({value:{},channels:o},a),l={channels:[{op:"replace",path:"/0",value:n[0]}]},i=await t.patch(l,c,a);e.expect(i.channels).toEqual(o);const u=await t.get(c,{},a);e.expect(u.channels).toEqual(n),await t.delete(c,a)})),e.it("patch 'increment' with test",(async()=>{const t=s(),a=p(),o=await t.put({value:{counter:1},channels:[]},a),n=await t.patch({value:[{op:"test",path:"/counter",value:1},{op:"replace",path:"/counter",value:2}]},o,a);e.expect(n.value).toEqual({counter:1});const l=await t.get(n,{properties:{value:{properties:{counter:{type:"integer"}}}}});e.expect(l.value.counter).toEqual(2),await e.expect(t.patch({value:[{op:"test",path:"/counter",value:1},{op:"replace",path:"/counter",value:3}]},o,a)).rejects.toThrow(c)})),e.it("invalid patch",(async()=>{const t=s(),a=p(),o=i(),n=await t.put(o,a);await e.expect(t.patch({value:[{op:"add",path:"/root",value:[]},{op:"add",path:"/root/2",value:2}]},n,a)).rejects.toThrow(l)})),e.it("patch channels to be wrong",(async()=>{const t=s(),a=p(),o=i();o.allowed=[r()];const n=await t.put(o,a),c=[{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(const o of c)await e.expect(t.patch(o,n,a)).rejects.toThrow(l);const u=await t.get(n,{},a);e.expect(u.value).toEqual(o.value),e.expect(u.channels).toEqual(o.channels),e.expect(u.allowed).toEqual(o.allowed),e.expect(u.lastModified).toEqual(n.lastModified)}))}))},exports.graffitiDiscoverTests=(t,a,o)=>{e.describe("discover",(()=>{e.it("discover nothing",(async()=>{const a=t().discover([],{});e.expect(await a.next()).toHaveProperty("done",!0)})),e.it("discover single",(async()=>{const o=t(),n=a(),c=i(),l=await o.put(c,n),s=[r(),c.channels[0]],u=o.discover(s,{}),d=await p(u);e.expect(d.value).toEqual(c.value),e.expect(d.channels).toEqual([c.channels[0]]),e.expect(d.allowed).toBeUndefined(),e.expect(d.actor).toEqual(n.actor),e.expect(d.tombstone).toBe(!1),e.expect(d.lastModified).toEqual(l.lastModified);const v=await u.next();e.expect(v.done).toBe(!0)})),e.it("discover wrong channel",(async()=>{const o=t(),n=a(),c=i();await o.put(c,n);const l=o.discover([r()],{});await e.expect(l.next()).resolves.toHaveProperty("done",!0)})),e.it("discover not allowed",(async()=>{const n=t(),c=a(),l=o(),s=i();s.allowed=[r(),r()];const u=await n.put(s,c),d=n.discover(s.channels,{},c),v=await p(d);e.expect(v.value).toEqual(s.value),e.expect(v.channels).toEqual(s.channels),e.expect(v.allowed).toEqual(s.allowed),e.expect(v.actor).toEqual(c.actor),e.expect(v.tombstone).toBe(!1),e.expect(v.lastModified).toEqual(u.lastModified);const h=n.discover(s.channels,{},l);e.expect(await h.next()).toHaveProperty("done",!0);const x=n.discover(s.channels,{});e.expect(await x.next()).toHaveProperty("done",!0)})),e.it("discover allowed",(async()=>{const n=t(),c=a(),l=o(),s=i();s.allowed=[r(),l.actor,r()];const u=await n.put(s,c),d=n.discover(s.channels,{},l),v=await p(d);e.expect(v.value).toEqual(s.value),e.expect(v.allowed).toEqual([l.actor]),e.expect(v.channels).toEqual(s.channels),e.expect(v.actor).toEqual(c.actor),e.expect(v.tombstone).toBe(!1),e.expect(v.lastModified).toEqual(u.lastModified)}));for(const n of["name","actor","lastModified"])e.it(`discover for ${n}`,(async()=>{const c=t(),l=a(),s=o(),r=i(),u=await c.put(r,l),d=i();d.channels=r.channels,await new Promise((e=>setTimeout(e,20)));const v=await c.put(d,s),h=c.discover(r.channels,{properties:{[n]:{enum:[u[n]]}}}),x=await p(h);e.expect(x.name).toEqual(u.name),e.expect(x.name).not.toEqual(v.name),e.expect(x.value).toEqual(r.value),await e.expect(h.next()).resolves.toHaveProperty("done",!0)}));e.it("discover with lastModified range",(async()=>{const o=t(),n=a(),c=i(),l=await o.put(c,n);await new Promise((e=>setTimeout(e,20)));const s=await o.put(c,n);e.expect(l.name).not.toEqual(s.name),e.expect(l.lastModified).toBeLessThan(s.lastModified);const r=o.discover([c.channels[0]],{properties:{lastModified:{minimum:s.lastModified,exclusiveMinimum:!0}}});e.expect(await r.next()).toHaveProperty("done",!0);const u=o.discover([c.channels[0]],{properties:{lastModified:{minimum:s.lastModified-.1,exclusiveMinimum:!0}}}),d=await p(u);e.expect(d.name).toEqual(s.name),e.expect(await u.next()).toHaveProperty("done",!0);const v=o.discover(c.channels,{properties:{value:{},lastModified:{minimum:s.lastModified}}}),h=await p(v);e.expect(h.name).toEqual(s.name),e.expect(await v.next()).toHaveProperty("done",!0);const x=o.discover(c.channels,{properties:{lastModified:{minimum:s.lastModified+.1}}});e.expect(await x.next()).toHaveProperty("done",!0);const w=o.discover(c.channels,{properties:{lastModified:{maximum:l.lastModified,exclusiveMaximum:!0}}});e.expect(await w.next()).toHaveProperty("done",!0);const m=o.discover(c.channels,{properties:{lastModified:{maximum:l.lastModified+.1,exclusiveMaximum:!0}}}),E=await p(m);e.expect(E.name).toEqual(l.name),e.expect(await m.next()).toHaveProperty("done",!0);const f=o.discover(c.channels,{properties:{lastModified:{maximum:l.lastModified}}}),y=await p(f);e.expect(y.name).toEqual(l.name),e.expect(await f.next()).toHaveProperty("done",!0);const q=o.discover(c.channels,{properties:{lastModified:{maximum:l.lastModified-.1}}});e.expect(await q.next()).toHaveProperty("done",!0)})),e.it("discover schema allowed, as and not as owner",(async()=>{const n=t(),c=a(),l=o(),s=i();s.allowed=[r(),l.actor,r()],await n.put(s,c);const u=n.discover(s.channels,{properties:{allowed:{minItems:3,not:{items:{not:{enum:[l.actor]}}}}}},c),d=await p(u);e.expect(d.value).toEqual(s.value),await e.expect(u.next()).resolves.toHaveProperty("done",!0);const v=n.discover(s.channels,{properties:{allowed:{minItems:3}}},l);await e.expect(v.next()).resolves.toHaveProperty("done",!0);const h=n.discover(s.channels,{properties:{allowed:{not:{items:{not:{enum:[s.channels[0]]}}}}}},l);await e.expect(h.next()).resolves.toHaveProperty("done",!0);const x=n.discover(s.channels,{properties:{allowed:{maxItems:1,not:{items:{not:{enum:[l.actor]}}}}}},l),w=await p(x);e.expect(w.value).toEqual(s.value),await e.expect(x.next()).resolves.toHaveProperty("done",!0)})),e.it("discover schema channels, as and not as owner",(async()=>{const n=t(),c=a(),l=o(),s=i();s.channels=[r(),r(),r()],await n.put(s,c);const u=n.discover([s.channels[0],s.channels[2]],{properties:{channels:{minItems:3,not:{items:{not:{enum:[s.channels[1]]}}}}}},c),d=await p(u);e.expect(d.value).toEqual(s.value),await e.expect(u.next()).resolves.toHaveProperty("done",!0);const v=n.discover([s.channels[0],s.channels[2]],{properties:{channels:{minItems:3}}},l);await e.expect(v.next()).resolves.toHaveProperty("done",!0);const h=n.discover([s.channels[0],s.channels[2]],{properties:{channels:{not:{items:{not:{enum:[s.channels[1]]}}}}}},l);await e.expect(h.next()).resolves.toHaveProperty("done",!0);const x=n.discover([s.channels[0],s.channels[2]],{properties:{allowed:{maxItems:2,not:{items:{not:{enum:[s.channels[2]]}}}}}},l),w=await p(x);e.expect(w.value).toEqual(s.value),await e.expect(x.next()).resolves.toHaveProperty("done",!0)})),e.it("discover query for empty allowed",(async()=>{const o=t(),n=a(),c=i(),l={not:{required:["allowed"]}};await o.put(c,n);const s=o.discover(c.channels,l,n),r=await p(s);e.expect(r.value).toEqual(c.value),e.expect(r.allowed).toBeUndefined(),await e.expect(s.next()).resolves.toHaveProperty("done",!0);const u=i();u.allowed=[],await o.put(u,n);const d=o.discover(u.channels,l,n);await e.expect(d.next()).resolves.toHaveProperty("done",!0)})),e.it("discover query for values",(async()=>{const o=t(),n=a(),c=i();c.value={test:r()},await o.put(c,n);const l=i();l.channels=c.channels,l.value={test:r(),something:r()},await o.put(l,n);const s=i();s.channels=c.channels,s.value={other:r(),something:r()},await o.put(s,n);const p=new Map;for(const t of["test","something","other"]){let a=0;for await(const n of o.discover(c.channels,{properties:{value:{required:[t]}}}))e.assert(!n.error,"result has error"),t in n.value.value&&a++;p.set(t,a)}e.expect(p.get("test")).toBe(2),e.expect(p.get("something")).toBe(2),e.expect(p.get("other")).toBe(1)})),e.it("discover for deleted content",(async()=>{const o=t(),n=a(),c=i(),l=await o.put(c,n),s=await o.delete(l,n),r=o.discover(c.channels,{}),u=await p(r);e.expect(u.tombstone).toBe(!0),e.expect(u.value).toEqual(c.value),e.expect(u.channels).toEqual(c.channels),e.expect(u.actor).toEqual(n.actor),e.expect(u.lastModified).toEqual(s.lastModified),await e.expect(r.next()).resolves.toHaveProperty("done",!0)})),e.it("discover for replaced channels",(async()=>{for(let o=0;o<10;o++){const o=t(),n=a(),c=i(),l=await o.put(c,n),s=i(),r=await o.put({...l,...s},n),u=o.discover(c.channels,{}),d=await p(u);await e.expect(u.next()).resolves.toHaveProperty("done",!0);const v=o.discover(s.channels,{}),h=await p(v);await e.expect(v.next()).resolves.toHaveProperty("done",!0),l.lastModified===r.lastModified?(e.expect(d.tombstone||h.tombstone).toBe(!0),e.expect(d.tombstone&&h.tombstone).toBe(!1)):(e.expect(d.tombstone).toBe(!0),e.expect(d.value).toEqual(c.value),e.expect(d.channels).toEqual(c.channels),e.expect(d.lastModified).toEqual(r.lastModified),e.expect(h.tombstone).toBe(!1),e.expect(h.value).toEqual(s.value),e.expect(h.channels).toEqual(s.channels),e.expect(h.lastModified).toEqual(r.lastModified))}})),e.it("discover for patched allowed",(async()=>{const o=t(),n=a(),c=i(),l=await o.put(c,n);await o.patch({allowed:[{op:"add",path:"",value:[]}]},l,n);const s=o.discover(c.channels,{}),r=await p(s);e.expect(r.tombstone).toBe(!0),e.expect(r.value).toEqual(c.value),e.expect(r.channels).toEqual(c.channels),e.expect(r.allowed).toBeUndefined(),await e.expect(s.next()).resolves.toHaveProperty("done",!0)})),e.it("put concurrently and discover one",(async()=>{const o=t(),n=a(),c=i();c.name=r();const l=Array(100).fill(0).map((()=>o.put(c,n)));await Promise.all(l);const s=o.discover(c.channels,{});let p=0,u=0;for await(const t of s)e.assert(!t.error,"result has error"),t.value.tombstone?p++:u++;e.expect(p).toBe(99),e.expect(u).toBe(1)}))}))},exports.graffitiLocationTests=t=>{e.describe("URI and location conversion",(()=>{e.it("location to uri and back",(async()=>{const a=t(),o={name:r(),actor:r(),source:r()},n=a.locationToUri(o),c=a.uriToLocation(n);e.expect(o).toEqual(c)})),e.it("collision resistance",(async()=>{const a=t(),o={name:r(),actor:r(),source:r()};for(const t of["name","actor","source"]){const n={...o,[t]:r()},c=a.locationToUri(o),l=a.locationToUri(n);e.expect(c).not.toEqual(l)}})),e.it("random URI should not be a valid location",(async()=>{const a=t();e.expect((()=>a.uriToLocation(""))).toThrow(s)}))}))},exports.graffitiSynchronizeTests=(t,a,o)=>{e.describe("synchronize",(()=>{e.it("get",(async()=>{const o=t(),n=a(),c=i(),l=c.channels.slice(1),s=await o.put(c,n),r=t(),p=r.synchronize(l,{}).next(),u=await r.get(s,{},n),d=(await p).value;if(!d||d.error)throw new Error("Error in synchronize");e.expect(d.value.value).toEqual(c.value),e.expect(d.value.channels).toEqual(l),e.expect(d.value.tombstone).toBe(!1),e.expect(d.value.lastModified).toEqual(u.lastModified)})),e.it("put",(async()=>{const o=t(),n=a(),c=r(),l=r(),s=r(),i={hello:"world"},p=[c,s],u=await o.put({value:i,channels:p},n),d=o.synchronize([c],{}).next(),v=o.synchronize([l],{}).next(),h=o.synchronize([s],{}).next(),x={goodbye:"world"},w=[l,s];await o.put({...u,value:x,channels:w},n);const m=(await d).value,E=(await v).value,f=(await h).value;if(!m||m.error||!E||E.error||!f||f.error)throw new Error("Error in synchronize");e.expect(m.value.value).toEqual(i),e.expect(m.value.channels).toEqual([c]),e.expect(m.value.tombstone).toBe(!0),e.expect(E.value.value).toEqual(x),e.expect(E.value.channels).toEqual([l]),e.expect(E.value.tombstone).toBe(!1),e.expect(f.value.value).toEqual(x),e.expect(f.value.channels).toEqual([s]),e.expect(f.value.tombstone).toBe(!1),e.expect(m.value.lastModified).toEqual(E.value.lastModified),e.expect(f.value.lastModified).toEqual(E.value.lastModified)})),e.it("patch",(async()=>{const o=t(),n=a(),c=r(),l=r(),s=r(),i={hello:"world"},p=[c,s],u=await o.put({value:i,channels:p},n),d=o.synchronize([c],{}).next(),v=o.synchronize([l],{}).next(),h=o.synchronize([s],{}).next();await o.patch({value:[{op:"add",path:"/something",value:"new value"}],channels:[{op:"add",path:"/-",value:l},{op:"remove",path:`/${p.indexOf(c)}`}]},u,n);const x=(await d).value,w=(await v).value,m=(await h).value;if(!x||x.error||!w||w.error||!m||m.error)throw new Error("Error in synchronize");const E={...i,something:"new value"};e.expect(x.value.value).toEqual(i),e.expect(x.value.channels).toEqual([c]),e.expect(x.value.tombstone).toBe(!0),e.expect(w.value.value).toEqual(E),e.expect(w.value.channels).toEqual([l]),e.expect(w.value.tombstone).toBe(!1),e.expect(m.value.value).toEqual(E),e.expect(m.value.channels).toEqual([s]),e.expect(m.value.tombstone).toBe(!1),e.expect(x.value.lastModified).toEqual(w.value.lastModified),e.expect(m.value.lastModified).toEqual(w.value.lastModified)})),e.it("delete",(async()=>{const o=t(),n=a(),c=[r(),r(),r()],l={hello:"world"},s=[r(),...c.slice(1)],i=await o.put({value:l,channels:s},n),p=o.synchronize(c,{}).next();o.delete(i,n);const u=(await p).value;if(!u||u.error)throw new Error("Error in synchronize");e.expect(u.value.tombstone).toBe(!0),e.expect(u.value.value).toEqual(l),e.expect(u.value.channels).toEqual(c.filter((e=>s.includes(e))))})),e.it("not allowed",(async()=>{const n=t(),c=a(),l=o(),s=[r(),r(),r()],i=s.slice(1),p=n.synchronize(i,{},c).next(),u=n.synchronize(i,{},l).next(),d=n.synchronize(i,{}).next(),v={hello:"world"},h=[r(),l.actor];await n.put({value:v,channels:s,allowed:h},c),await e.expect(Promise.race([d,new Promise(((e,t)=>setTimeout(t,100,"Timeout")))])).rejects.toThrow("Timeout");const x=(await p).value,w=(await u).value;if(!x||x.error||!w||w.error)throw new Error("Error in synchronize");e.expect(x.value.value).toEqual(v),e.expect(x.value.allowed).toEqual(h),e.expect(x.value.channels).toEqual(s),e.expect(w.value.value).toEqual(v),e.expect(w.value.allowed).toEqual([l.actor]),e.expect(w.value.channels).toEqual(i)}))}))};
|
|
2
|
-
//# sourceMappingURL=index.cjs.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs.js","sources":[],"sourcesContent":[],"names":[],"mappings":""}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"1-api.d.ts","sourceRoot":"","sources":["../../../src/1-api.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,gBAAgB,EAChB,cAAc,EACd,kBAAkB,EAClB,aAAa,EACb,eAAe,EACf,iBAAiB,EACjB,cAAc,EACf,MAAM,WAAW,CAAC;AACnB,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAE/C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2OG;AACH,8BAAsB,QAAQ;IAC5B;;;;;;;;;OASG;IACH,QAAQ,CAAC,aAAa,CAAC,QAAQ,EAAE,gBAAgB,GAAG,MAAM;IAE1D;;;;;;;;OAQG;IACH,QAAQ,CAAC,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,gBAAgB;IAErD;;;;OAIG;IACH,WAAW,CAAC,MAAM,EAAE,kBAAkB;IAItC;;;;;;;;;;;;;;;;;OAiBG;IACH,QAAQ,CAAC,GAAG,CAAC,MAAM;IACjB;;;;;OAKG;IACH,MAAM,EAAE,iBAAiB,CAAC,MAAM,CAAC;IACjC;;;OAGG;IACH,OAAO,EAAE,eAAe,GACvB,OAAO,CAAC,kBAAkB,CAAC;IAE9B;;;;;;;;;;;OAWG;IACH,QAAQ,CAAC,GAAG,CAAC,MAAM,SAAS,WAAW;IACrC;;OAEG;IACH,aAAa,EAAE,gBAAgB,GAAG,MAAM;IACxC;;OAEG;IACH,MAAM,EAAE,MAAM;IACd;;;;;OAKG;IACH,OAAO,CAAC,EAAE,eAAe,GACxB,OAAO,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC;IAElC;;;;;;;;;;;;OAYG;IACH,QAAQ,CAAC,KAAK;IACZ;;;OAGG;IACH,KAAK,EAAE,aAAa;IACpB;;OAEG;IACH,aAAa,EAAE,gBAAgB,GAAG,MAAM;IACxC;;;OAGG;IACH,OAAO,EAAE,eAAe,GACvB,OAAO,CAAC,kBAAkB,CAAC;IAE9B;;;;;;;;;;;;;;;OAeG;IACH,QAAQ,CAAC,MAAM;IACb;;OAEG;IACH,aAAa,EAAE,gBAAgB,GAAG,MAAM;IACxC;;;OAGG;IACH,OAAO,EAAE,eAAe,GACvB,OAAO,CAAC,kBAAkB,CAAC;IAE9B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OA+DG;IACH,QAAQ,CAAC,QAAQ,CAAC,MAAM,SAAS,WAAW;IAC1C;;OAEG;IACH,QAAQ,EAAE,MAAM,EAAE;IAClB;;OAEG;IACH,MAAM,EAAE,MAAM;IACd;;;;;OAKG;IACH,OAAO,CAAC,EAAE,eAAe,GACxB,cAAc,CACf,cAAc,CAAC,MAAM,CAAC,EACtB;QACE,kBAAkB,EAAE,MAAM,CAAC;KAC5B,CACF;IAED;;;;;;;;;;;;;;;;;;;;;;OAsBG;IACH,QAAQ,CAAC,WAAW,CAAC,MAAM,SAAS,WAAW;IAC7C;;OAEG;IACH,QAAQ,EAAE,MAAM,EAAE;IAClB;;OAEG;IACH,MAAM,EAAE,MAAM;IACd;;;;;OAKG;IACH,OAAO,CAAC,EAAE,eAAe,GACxB,cAAc,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC;IAEzC;;;;;;;;;;;;;;;OAeG;IACH,QAAQ,CAAC,YAAY;IACnB;;;OAGG;IACH,OAAO,EAAE,eAAe,GACvB,cAAc,CAAC;QAChB,OAAO,EAAE,MAAM,CAAC;QAChB,YAAY,EAAE,MAAM,CAAC;QACrB,KAAK,EAAE,MAAM,CAAC;KACf,CAAC;IAEF;;;;;;;;;;;;;;;OAeG;IACH,QAAQ,CAAC,WAAW,CAAC,OAAO,EAAE,eAAe,GAAG,cAAc,CAAC;QAC7D,IAAI,EAAE,MAAM,CAAC;QACb,MAAM,EAAE,MAAM,CAAC;QACf,YAAY,EAAE,MAAM,CAAC;KACtB,CAAC;IAEF;;OAEG;IAGH;;;;;;;;;;OAUG;IACH,QAAQ,CAAC,KAAK;IACZ;;;;OAIG;IACH,QAAQ,CAAC,EAAE;QACT;;;;;;;;WAQG;QACH,KAAK,CAAC,EAAE,MAAM,CAAC;QACf;;;;;;;;;;WAUG;QACH,KAAK,CAAC,EAAE,EAAE,CAAC;KACZ;IACD;;;;;OAKG;IACH,KAAK,CAAC,EAAE,MAAM,GACb,OAAO,CAAC,IAAI,CAAC;IAEhB;;;;;;;;;;OAUG;IACH,QAAQ,CAAC,MAAM;IACb;;OAEG;IACH,OAAO,EAAE,eAAe;IACxB;;;;OAIG;IACH,KAAK,CAAC,EAAE,MAAM,GACb,OAAO,CAAC,IAAI,CAAC;IAEhB;;;;;;;OAOG;IACH,QAAQ,CAAC,QAAQ,CAAC,aAAa,EAAE,WAAW,CAAC;CAC9C;AAED;;;;;GAKG;AACH,MAAM,MAAM,eAAe,GAAG,MAAM,QAAQ,CAAC"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"2-types.d.ts","sourceRoot":"","sources":["../../../src/2-types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AACjD,OAAO,KAAK,EAAE,SAAS,IAAI,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AAEvE;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,MAAM,WAAW,kBAAkB;IACjC;;;;;OAKG;IACH,KAAK,EAAE,EAAE,CAAC;IAEV;;;;;;;;;;;;OAYG;IACH,QAAQ,EAAE,MAAM,EAAE,CAAC;IAEnB;;;;;;;;;;;;;OAaG;IACH,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IAEnB;;;;;;;;;;;;OAYG;IACH,KAAK,EAAE,MAAM,CAAC;IAEd;;;;;;OAMG;IACH,IAAI,EAAE,MAAM,CAAC;IAEb;;;;;OAKG;IACH,MAAM,EAAE,MAAM,CAAC;IAEf;;;;;;;;;OASG;IACH,YAAY,EAAE,MAAM,CAAC;IAErB;;;OAGG;IACH,SAAS,EAAE,OAAO,CAAC;CACpB;AAED;;;;;;;GAOG;AACH,MAAM,MAAM,cAAc,CAAC,MAAM,IAAI,kBAAkB,GAAG,WAAW,CAAC,MAAM,CAAC,CAAC;AAE9E;;;;;;;;;GASG;AACH,MAAM,MAAM,gBAAgB,GAAG,IAAI,CACjC,kBAAkB,EAClB,OAAO,GAAG,MAAM,GAAG,QAAQ,CAC5B,CAAC;AAEF;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,MAAM,iBAAiB,CAAC,MAAM,IAAI,IAAI,CAC1C,kBAAkB,EAClB,OAAO,GAAG,UAAU,GAAG,SAAS,CACjC,GACC,OAAO,CAAC,gBAAgB,CAAC,GACzB,WAAW,CAAC,MAAM,CAAC,CAAC;AAEtB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,MAAM,WAAW,eAAe;IAC9B;;OAEG;IACH,KAAK,EAAE,MAAM,CAAC;IACd;;;;;OAKG;IACH,KAAK,CAAC,EAAE,EAAE,CAAC;CACZ;AAED;;;;;;;;;GASG;AACH,MAAM,WAAW,aAAa;IAC5B;;;;OAIG;IACH,KAAK,CAAC,EAAE,kBAAkB,EAAE,CAAC;IAE7B;;;;OAIG;IACH,QAAQ,CAAC,EAAE,kBAAkB,EAAE,CAAC;IAEhC;;;;OAIG;IACH,OAAO,CAAC,EAAE,kBAAkB,EAAE,CAAC;CAChC;AAED;;;;;;;;;;;;;;;GAeG;AACH,MAAM,MAAM,cAAc,CAAC,MAAM,EAAE,OAAO,GAAG,IAAI,IAAI,cAAc,CAC/D;IACE,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;CACf,GACD;IACE,KAAK,EAAE,KAAK,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;CAChB,EACH,OAAO,CACR,CAAC;AAEF;;;;;GAKG;AACH,MAAM,MAAM,kBAAkB,GAAG,WAAW,CAC1C;IACE,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,GAAG,CACA;IACE,KAAK,EAAE,KAAK,CAAC;IACb,OAAO,CAAC,EAAE,SAAS,CAAC;CACrB,GACD;IACE,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB,OAAO,EAAE,eAAe,CAAC;CAC1B,CACJ,CACF,CAAC;AAEF;;;;;GAKG;AACH,MAAM,MAAM,mBAAmB,GAAG,WAAW,CAAC;IAC5C,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,KAAK,CAAC;CACf,CAAC,CAAC"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"3-errors.d.ts","sourceRoot":"","sources":["../../../src/3-errors.ts"],"names":[],"mappings":"AAAA,qBAAa,yBAA0B,SAAQ,KAAK;gBACtC,OAAO,CAAC,EAAE,MAAM;CAK7B;AAED,qBAAa,sBAAuB,SAAQ,KAAK;gBACnC,OAAO,CAAC,EAAE,MAAM;CAK7B;AAED,qBAAa,qBAAsB,SAAQ,KAAK;gBAClC,OAAO,CAAC,EAAE,MAAM;CAK7B;AAED,qBAAa,0BAA2B,SAAQ,KAAK;gBACvC,OAAO,CAAC,EAAE,MAAM;CAK7B;AAED,qBAAa,2BAA4B,SAAQ,KAAK;gBACxC,OAAO,CAAC,EAAE,MAAM;CAK7B;AAED,qBAAa,4BAA6B,SAAQ,KAAK;gBACzC,OAAO,CAAC,EAAE,MAAM;CAK7B;AAED,qBAAa,uBAAwB,SAAQ,KAAK;gBACpC,OAAO,CAAC,EAAE,MAAM;CAK7B;AAED,qBAAa,uBAAwB,SAAQ,KAAK;gBACpC,OAAO,CAAC,EAAE,MAAM;CAK7B"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,SAAS,CAAC;AACxB,cAAc,WAAW,CAAC;AAC1B,cAAc,YAAY,CAAC;AAC3B,YAAY,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"crud.d.ts","sourceRoot":"","sources":["../../../tests/crud.ts"],"names":[],"mappings":"AACA,OAAO,EACL,KAAK,eAAe,EACpB,KAAK,eAAe,EAQrB,MAAM,cAAc,CAAC;AAGtB,eAAO,MAAM,iBAAiB,gBACf,eAAe,eACf,MAAM,eAAe,eACrB,MAAM,eAAe,SAucnC,CAAC"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"discover.d.ts","sourceRoot":"","sources":["../../../tests/discover.ts"],"names":[],"mappings":"AACA,OAAO,EACL,KAAK,eAAe,EACpB,KAAK,eAAe,EAGrB,MAAM,cAAc,CAAC;AAGtB,eAAO,MAAM,qBAAqB,gBACnB,eAAe,eACf,MAAM,eAAe,eACrB,MAAM,eAAe,SA0kBnC,CAAC"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../tests/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC;AAC3B,cAAc,QAAQ,CAAC;AACvB,cAAc,eAAe,CAAC;AAC9B,cAAc,YAAY,CAAC"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"location.d.ts","sourceRoot":"","sources":["../../../tests/location.ts"],"names":[],"mappings":"AACA,OAAO,EAA2B,KAAK,eAAe,EAAE,MAAM,cAAc,CAAC;AAG7E,eAAO,MAAM,qBAAqB,gBAAiB,eAAe,SAkCjE,CAAC"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"synchronize.d.ts","sourceRoot":"","sources":["../../../tests/synchronize.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,eAAe,EAAE,KAAK,eAAe,EAAE,MAAM,cAAc,CAAC;AAG1E,eAAO,MAAM,wBAAwB,gBACtB,eAAe,eACf,MAAM,eAAe,eACrB,MAAM,eAAe,SA2PnC,CAAC"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../tests/utils.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,iBAAiB,EAAE,cAAc,EAAE,MAAM,QAAQ,CAAC;AAEhE,wBAAgB,YAAY,IAAI,MAAM,CAMrC;AAED,wBAAgB,WAAW;;EAI1B;AAED,wBAAgB,eAAe,IAAI,iBAAiB,CAAC,EAAE,CAAC,CAKvD;AAED,wBAAsB,eAAe,CAAC,CAAC,EAAE,CAAC,EAAE,QAAQ,EAAE,cAAc,CAAC,CAAC,EAAE,CAAC,CAAC,cAIzE"}
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|