@graffiti-garden/api 0.3.0 → 0.4.0

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.
@@ -1 +1 @@
1
- {"version":3,"file":"2-types.d.ts","sourceRoot":"","sources":["../../src/2-types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"2-types.d.ts","sourceRoot":"","sources":["../../src/2-types.ts"],"names":[],"mappings":"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"}
@@ -1,5 +1,5 @@
1
1
  export * from "./1-api";
2
2
  export * from "./2-types";
3
3
  export * from "./3-errors";
4
- export type { JSONSchema4 } from "json-schema";
4
+ export type { JSONSchema } from "json-schema-to-ts";
5
5
  //# sourceMappingURL=index.d.ts.map
@@ -1 +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"}
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,UAAU,EAAE,MAAM,mBAAmB,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"crud.d.ts","sourceRoot":"","sources":["../../tests/crud.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,QAAQ,EACR,eAAe,EAEhB,MAAM,sBAAsB,CAAC;AAW9B,eAAO,MAAM,iBAAiB,gBACf,MAAM,IAAI,CAAC,QAAQ,EAAE,KAAK,GAAG,KAAK,GAAG,QAAQ,GAAG,OAAO,CAAC,eACxD,MAAM,eAAe,GAAG,OAAO,CAAC,eAAe,CAAC,eAChD,MAAM,eAAe,GAAG,OAAO,CAAC,eAAe,CAAC,SA0c9D,CAAC"}
1
+ {"version":3,"file":"crud.d.ts","sourceRoot":"","sources":["../../tests/crud.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,QAAQ,EACR,eAAe,EAGhB,MAAM,sBAAsB,CAAC;AAY9B,eAAO,MAAM,iBAAiB,gBACf,MAAM,IAAI,CAAC,QAAQ,EAAE,KAAK,GAAG,KAAK,GAAG,QAAQ,GAAG,OAAO,CAAC,eACxD,MAAM,eAAe,GAAG,OAAO,CAAC,eAAe,CAAC,eAChD,MAAM,eAAe,GAAG,OAAO,CAAC,eAAe,CAAC,SA+d9D,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"discover.d.ts","sourceRoot":"","sources":["../../tests/discover.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,QAAQ,EACR,eAAe,EAEhB,MAAM,sBAAsB,CAAC;AAG9B,eAAO,MAAM,qBAAqB,gBACnB,MAAM,IAAI,CAAC,QAAQ,EAAE,UAAU,GAAG,KAAK,GAAG,QAAQ,GAAG,OAAO,CAAC,eAC7D,MAAM,eAAe,GAAG,OAAO,CAAC,eAAe,CAAC,eAChD,MAAM,eAAe,GAAG,OAAO,CAAC,eAAe,CAAC,SAwiB9D,CAAC"}
1
+ {"version":3,"file":"discover.d.ts","sourceRoot":"","sources":["../../tests/discover.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,QAAQ,EACR,eAAe,EAEhB,MAAM,sBAAsB,CAAC;AAG9B,eAAO,MAAM,qBAAqB,gBACnB,MAAM,IAAI,CAAC,QAAQ,EAAE,UAAU,GAAG,KAAK,GAAG,QAAQ,GAAG,OAAO,CAAC,eAC7D,MAAM,eAAe,GAAG,OAAO,CAAC,eAAe,CAAC,eAChD,MAAM,eAAe,GAAG,OAAO,CAAC,eAAe,CAAC,SAoiB9D,CAAC"}
package/dist/tests.mjs CHANGED
@@ -174,15 +174,31 @@ var graffitiCRUDTests = (useGraffiti, useSession1, useSession2) => {
174
174
  type: "string"
175
175
  },
176
176
  another: {
177
- type: "integer"
177
+ type: "array",
178
+ items: {
179
+ type: "number"
180
+ }
181
+ },
182
+ deeper: {
183
+ type: "object",
184
+ properties: {
185
+ deepProp: {
186
+ type: "string"
187
+ }
188
+ },
189
+ required: ["deepProp"]
178
190
  }
179
- }
191
+ },
192
+ required: ["another", "deeper"]
180
193
  }
181
194
  }
182
195
  };
183
196
  const goodValue = {
184
197
  something: "hello",
185
- another: 42
198
+ another: [1, 2, 3],
199
+ deeper: {
200
+ deepProp: "hello"
201
+ }
186
202
  };
187
203
  const putted = await graffiti.put(
188
204
  {
@@ -194,9 +210,14 @@ var graffitiCRUDTests = (useGraffiti, useSession1, useSession2) => {
194
210
  const gotten = await graffiti.get(putted, schema);
195
211
  expect2(gotten.value.something).toEqual(goodValue.something);
196
212
  expect2(gotten.value.another).toEqual(goodValue.another);
213
+ expect2(gotten.value.another[0]).toEqual(1);
214
+ expect2(gotten.value.deeper.deepProp).toEqual(goodValue.deeper.deepProp);
197
215
  });
198
216
  it2("put and get with invalid schema", async () => {
199
- const putted = await graffiti.put({ value: {}, channels: [] }, session);
217
+ const putted = await graffiti.put(
218
+ { value: {}, channels: [] },
219
+ session
220
+ );
200
221
  await expect2(
201
222
  graffiti.get(putted, {
202
223
  properties: {
@@ -571,8 +592,7 @@ var graffitiDiscoverTests = (useGraffiti, useSession1, useSession2) => {
571
592
  const gtIterator = graffiti.discover([object.channels[0]], {
572
593
  properties: {
573
594
  lastModified: {
574
- minimum: putted2.lastModified,
575
- exclusiveMinimum: true
595
+ exclusiveMinimum: putted2.lastModified
576
596
  }
577
597
  }
578
598
  });
@@ -580,8 +600,7 @@ var graffitiDiscoverTests = (useGraffiti, useSession1, useSession2) => {
580
600
  const gtIteratorEpsilon = graffiti.discover([object.channels[0]], {
581
601
  properties: {
582
602
  lastModified: {
583
- minimum: putted2.lastModified - 0.1,
584
- exclusiveMinimum: true
603
+ exclusiveMinimum: putted2.lastModified - 0.1
585
604
  }
586
605
  }
587
606
  });
@@ -610,8 +629,7 @@ var graffitiDiscoverTests = (useGraffiti, useSession1, useSession2) => {
610
629
  const ltIterator = graffiti.discover(object.channels, {
611
630
  properties: {
612
631
  lastModified: {
613
- maximum: putted1.lastModified,
614
- exclusiveMaximum: true
632
+ exclusiveMaximum: putted1.lastModified
615
633
  }
616
634
  }
617
635
  });
@@ -619,8 +637,7 @@ var graffitiDiscoverTests = (useGraffiti, useSession1, useSession2) => {
619
637
  const ltIteratorEpsilon = graffiti.discover(object.channels, {
620
638
  properties: {
621
639
  lastModified: {
622
- maximum: putted1.lastModified + 0.1,
623
- exclusiveMaximum: true
640
+ exclusiveMaximum: putted1.lastModified + 0.1
624
641
  }
625
642
  }
626
643
  });
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../tests/location.ts", "../tests/utils.ts", "../tests/crud.ts", "../tests/discover.ts", "../tests/orphans.ts", "../tests/channel-stats.ts"],
4
- "sourcesContent": ["import { it, expect, describe } from \"vitest\";\nimport type { Graffiti } from \"@graffiti-garden/api\";\nimport { GraffitiErrorInvalidUri } from \"@graffiti-garden/api\";\nimport { randomString } from \"./utils\";\n\nexport const graffitiLocationTests = (\n useGraffiti: () => Pick<Graffiti, \"locationToUri\" | \"uriToLocation\">,\n) => {\n describe.concurrent(\"URI and location conversion\", () => {\n it(\"location to uri and back\", async () => {\n const graffiti = useGraffiti();\n const location = {\n name: randomString(),\n actor: randomString(),\n source: randomString(),\n };\n const uri = graffiti.locationToUri(location);\n const location2 = graffiti.uriToLocation(uri);\n expect(location).toEqual(location2);\n });\n\n it(\"collision resistance\", async () => {\n const graffiti = useGraffiti();\n const location1 = {\n name: randomString(),\n actor: randomString(),\n source: randomString(),\n };\n for (const prop of [\"name\", \"actor\", \"source\"] as const) {\n const location2 = { ...location1, [prop]: randomString() };\n const uri1 = graffiti.locationToUri(location1);\n const uri2 = graffiti.locationToUri(location2);\n expect(uri1).not.toEqual(uri2);\n }\n });\n\n it(\"random URI should not be a valid location\", async () => {\n const graffiti = useGraffiti();\n expect(() => graffiti.uriToLocation(\"\")).toThrow(GraffitiErrorInvalidUri);\n });\n });\n};\n", "import { assert } from \"vitest\";\nimport type { GraffitiPutObject, GraffitiStream } from \"@graffiti-garden/api\";\n\nexport function randomString(): string {\n const array = new Uint8Array(16);\n crypto.getRandomValues(array);\n const str = Array.from(array)\n .map((b) => b.toString(16).padStart(2, \"0\"))\n .join(\"\");\n\n // check for unicode support\n return str + \"\uD83D\uDC69\uD83C\uDFFD\u200D\u2764\uFE0F\u200D\uD83D\uDC8B\u200D\uD83D\uDC69\uD83C\uDFFB\uD83E\uDEF1\uD83C\uDFFC\u200D\uD83E\uDEF2\uD83C\uDFFF\";\n}\n\nexport function randomValue() {\n return {\n [randomString()]: randomString(),\n };\n}\n\nexport function randomPutObject(): GraffitiPutObject<{}> {\n return {\n value: randomValue(),\n channels: [randomString(), randomString()],\n };\n}\n\nexport async function nextStreamValue<S, T>(iterator: GraffitiStream<S, T>) {\n const result = await iterator.next();\n assert(!result.done && !result.value.error, \"result has no value\");\n return result.value.value;\n}\n", "import { it, expect, describe, beforeAll } from \"vitest\";\nimport type {\n Graffiti,\n GraffitiSession,\n GraffitiPatch,\n} from \"@graffiti-garden/api\";\nimport {\n GraffitiErrorNotFound,\n GraffitiErrorSchemaMismatch,\n GraffitiErrorInvalidSchema,\n GraffitiErrorForbidden,\n GraffitiErrorPatchTestFailed,\n GraffitiErrorPatchError,\n} from \"@graffiti-garden/api\";\nimport { randomPutObject, randomString } from \"./utils\";\n\nexport const graffitiCRUDTests = (\n useGraffiti: () => Pick<Graffiti, \"put\" | \"get\" | \"delete\" | \"patch\">,\n useSession1: () => GraffitiSession | Promise<GraffitiSession>,\n useSession2: () => GraffitiSession | Promise<GraffitiSession>,\n) => {\n describe.concurrent(\n \"CRUD\",\n {\n timeout: 20000,\n },\n () => {\n let graffiti: ReturnType<typeof useGraffiti>;\n let session: GraffitiSession;\n let session1: GraffitiSession;\n let session2: GraffitiSession;\n beforeAll(async () => {\n graffiti = useGraffiti();\n session1 = await useSession1();\n session = session1;\n session2 = await useSession2();\n });\n\n it(\"put, get, delete\", async () => {\n const value = {\n something: \"hello, world~ c:\",\n };\n const channels = [randomString(), randomString()];\n\n // Put the object\n const previous = await graffiti.put({ value, channels }, session);\n expect(previous.value).toEqual({});\n expect(previous.channels).toEqual([]);\n expect(previous.allowed).toBeUndefined();\n expect(previous.actor).toEqual(session.actor);\n\n // Get it back\n const gotten = await graffiti.get(previous, {});\n expect(gotten.value).toEqual(value);\n expect(gotten.channels).toEqual([]);\n expect(gotten.allowed).toBeUndefined();\n expect(gotten.name).toEqual(previous.name);\n expect(gotten.actor).toEqual(previous.actor);\n expect(gotten.source).toEqual(previous.source);\n expect(gotten.lastModified).toEqual(previous.lastModified);\n\n // Replace it\n const newValue = {\n something: \"goodbye, world~ :c\",\n };\n const beforeReplaced = await graffiti.put(\n { ...previous, value: newValue, channels: [] },\n session,\n );\n expect(beforeReplaced.value).toEqual(value);\n expect(beforeReplaced.tombstone).toEqual(true);\n expect(beforeReplaced.name).toEqual(previous.name);\n expect(beforeReplaced.actor).toEqual(previous.actor);\n expect(beforeReplaced.source).toEqual(previous.source);\n expect(beforeReplaced.lastModified).toBeGreaterThanOrEqual(\n gotten.lastModified,\n );\n\n // Get it again\n const afterReplaced = await graffiti.get(previous, {});\n expect(afterReplaced.value).toEqual(newValue);\n expect(afterReplaced.lastModified).toEqual(beforeReplaced.lastModified);\n expect(afterReplaced.tombstone).toEqual(false);\n\n // Delete it\n const beforeDeleted = await graffiti.delete(afterReplaced, session);\n expect(beforeDeleted.tombstone).toEqual(true);\n expect(beforeDeleted.value).toEqual(newValue);\n expect(beforeDeleted.lastModified).toBeGreaterThanOrEqual(\n beforeReplaced.lastModified,\n );\n\n // Get a tombstone\n const final = await graffiti.get(afterReplaced, {});\n expect(final).toEqual(beforeDeleted);\n });\n\n it(\"get non-existant\", async () => {\n const putted = await graffiti.put(randomPutObject(), session);\n await expect(\n graffiti.get(\n {\n ...putted,\n name: randomString(),\n },\n {},\n ),\n ).rejects.toBeInstanceOf(GraffitiErrorNotFound);\n });\n\n it(\"put, get, delete with wrong actor\", async () => {\n await expect(\n graffiti.put(\n { value: {}, channels: [], actor: session2.actor },\n session1,\n ),\n ).rejects.toThrow(GraffitiErrorForbidden);\n\n const putted = await graffiti.put(\n { value: {}, channels: [] },\n session2,\n );\n\n await expect(graffiti.delete(putted, session1)).rejects.toThrow(\n GraffitiErrorForbidden,\n );\n\n await expect(graffiti.patch({}, putted, session1)).rejects.toThrow(\n GraffitiErrorForbidden,\n );\n });\n\n it(\"put and get with schema\", async () => {\n const schema = {\n properties: {\n value: {\n properties: {\n something: {\n type: \"string\",\n },\n another: {\n type: \"integer\",\n },\n },\n },\n },\n } as const;\n\n const goodValue = {\n something: \"hello\",\n another: 42,\n } as const;\n\n const putted = await graffiti.put<typeof schema>(\n {\n value: goodValue,\n channels: [],\n },\n session,\n );\n\n const gotten = await graffiti.get(putted, schema);\n expect(gotten.value.something).toEqual(goodValue.something);\n expect(gotten.value.another).toEqual(goodValue.another);\n });\n\n it(\"put and get with invalid schema\", async () => {\n const putted = await graffiti.put({ value: {}, channels: [] }, session);\n await expect(\n graffiti.get(putted, {\n properties: {\n value: {\n //@ts-ignore\n type: \"asdf\",\n },\n },\n }),\n ).rejects.toThrow(GraffitiErrorInvalidSchema);\n });\n\n it(\"put and get with wrong schema\", async () => {\n const putted = await graffiti.put(\n {\n value: {\n hello: \"world\",\n },\n channels: [],\n },\n session,\n );\n\n await expect(\n graffiti.get(putted, {\n properties: {\n value: {\n properties: {\n hello: {\n type: \"number\",\n },\n },\n },\n },\n }),\n ).rejects.toThrow(GraffitiErrorSchemaMismatch);\n });\n\n it(\"put and get with empty access control\", async () => {\n const value = {\n um: \"hi\",\n };\n const allowed = [randomString()];\n const channels = [randomString()];\n const putted = await graffiti.put(\n { value, allowed, channels },\n session1,\n );\n\n // Get it with authenticated session\n const gotten = await graffiti.get(putted, {}, session1);\n expect(gotten.value).toEqual(value);\n expect(gotten.allowed).toEqual(allowed);\n expect(gotten.channels).toEqual(channels);\n\n // But not without session\n await expect(graffiti.get(putted, {})).rejects.toBeInstanceOf(\n GraffitiErrorNotFound,\n );\n\n // Or the wrong session\n await expect(graffiti.get(putted, {}, session2)).rejects.toBeInstanceOf(\n GraffitiErrorNotFound,\n );\n });\n\n it(\"put and get with specific access control\", async () => {\n const value = {\n um: \"hi\",\n };\n const allowed = [randomString(), session2.actor, randomString()];\n const channels = [randomString()];\n const putted = await graffiti.put(\n {\n value,\n allowed,\n channels,\n },\n session1,\n );\n\n // Get it with authenticated session\n const gotten = await graffiti.get(putted, {}, session1);\n expect(gotten.value).toEqual(value);\n expect(gotten.allowed).toEqual(allowed);\n expect(gotten.channels).toEqual(channels);\n\n // But not without session\n await expect(graffiti.get(putted, {})).rejects.toBeInstanceOf(\n GraffitiErrorNotFound,\n );\n\n const gotten2 = await graffiti.get(putted, {}, session2);\n expect(gotten2.value).toEqual(value);\n // They should only see that is is private to them\n expect(gotten2.allowed).toEqual([session2.actor]);\n // And not see any channels\n expect(gotten2.channels).toEqual([]);\n });\n\n it(\"patch value\", async () => {\n const value = {\n something: \"hello, world~ c:\",\n };\n const putted = await graffiti.put({ value, channels: [] }, session);\n\n // Wait just a bit to make sure the lastModified is different\n await new Promise((resolve) => setTimeout(resolve, 10));\n\n const patch: GraffitiPatch = {\n value: [\n { op: \"replace\", path: \"/something\", value: \"goodbye, world~ :c\" },\n ],\n };\n const beforePatched = await graffiti.patch(patch, putted, session);\n expect(beforePatched.value).toEqual(value);\n expect(beforePatched.tombstone).toBe(true);\n expect(beforePatched.lastModified).toBeGreaterThan(putted.lastModified);\n\n const gotten = await graffiti.get(putted, {});\n expect(gotten.value).toEqual({\n something: \"goodbye, world~ :c\",\n });\n expect(beforePatched.lastModified).toBe(gotten.lastModified);\n\n await graffiti.delete(putted, session);\n });\n\n it(\"patch deleted object\", async () => {\n const putted = await graffiti.put(randomPutObject(), session);\n const deleted = await graffiti.delete(putted, session);\n await expect(\n graffiti.patch({}, putted, session),\n ).rejects.toBeInstanceOf(GraffitiErrorNotFound);\n });\n\n it(\"deep patch\", async () => {\n const value = {\n something: {\n another: {\n somethingElse: \"hello\",\n },\n },\n };\n const putted = await graffiti.put(\n { value: value, channels: [] },\n session,\n );\n\n const beforePatch = await graffiti.patch(\n {\n value: [\n {\n op: \"replace\",\n path: \"/something/another/somethingElse\",\n value: \"goodbye\",\n },\n ],\n },\n putted,\n session,\n );\n const gotten = await graffiti.get(putted, {});\n\n expect(beforePatch.value).toEqual(value);\n expect(gotten.value).toEqual({\n something: {\n another: {\n somethingElse: \"goodbye\",\n },\n },\n });\n });\n\n it(\"patch channels\", async () => {\n const channelsBefore = [randomString()];\n const channelsAfter = [randomString()];\n\n const putted = await graffiti.put(\n { value: {}, channels: channelsBefore },\n session,\n );\n\n const patch: GraffitiPatch = {\n channels: [{ op: \"replace\", path: \"/0\", value: channelsAfter[0] }],\n };\n const patched = await graffiti.patch(patch, putted, session);\n expect(patched.channels).toEqual(channelsBefore);\n const gotten = await graffiti.get(putted, {}, session);\n expect(gotten.channels).toEqual(channelsAfter);\n await graffiti.delete(putted, session);\n });\n\n it(\"patch 'increment' with test\", async () => {\n const putted = await graffiti.put(\n {\n value: {\n counter: 1,\n },\n channels: [],\n },\n session,\n );\n\n const previous = await graffiti.patch(\n {\n value: [\n { op: \"test\", path: \"/counter\", value: 1 },\n { op: \"replace\", path: \"/counter\", value: 2 },\n ],\n },\n putted,\n session,\n );\n expect(previous.value).toEqual({ counter: 1 });\n const result = await graffiti.get(previous, {\n properties: {\n value: {\n properties: {\n counter: {\n type: \"integer\",\n },\n },\n },\n },\n });\n expect(result.value.counter).toEqual(2);\n\n await expect(\n graffiti.patch(\n {\n value: [\n { op: \"test\", path: \"/counter\", value: 1 },\n { op: \"replace\", path: \"/counter\", value: 3 },\n ],\n },\n putted,\n session,\n ),\n ).rejects.toThrow(GraffitiErrorPatchTestFailed);\n });\n\n it(\"invalid patch\", async () => {\n const object = randomPutObject();\n const putted = await graffiti.put(object, session);\n\n await expect(\n graffiti.patch(\n {\n value: [\n { op: \"add\", path: \"/root\", value: [] },\n { op: \"add\", path: \"/root/2\", value: 2 }, // out of bounds\n ],\n },\n putted,\n session,\n ),\n ).rejects.toThrow(GraffitiErrorPatchError);\n });\n\n it(\"patch channels to be wrong\", async () => {\n const object = randomPutObject();\n object.allowed = [randomString()];\n const putted = await graffiti.put(object, session);\n\n const patches: GraffitiPatch[] = [\n {\n channels: [{ op: \"replace\", path: \"\", value: null }],\n },\n {\n channels: [{ op: \"replace\", path: \"\", value: {} }],\n },\n {\n channels: [{ op: \"replace\", path: \"\", value: [\"hello\", [\"hi\"]] }],\n },\n {\n channels: [{ op: \"add\", path: \"/0\", value: 1 }],\n },\n {\n value: [{ op: \"replace\", path: \"\", value: \"not an object\" }],\n },\n {\n value: [{ op: \"replace\", path: \"\", value: null }],\n },\n {\n value: [{ op: \"replace\", path: \"\", value: [] }],\n },\n {\n allowed: [{ op: \"replace\", path: \"\", value: {} }],\n },\n {\n allowed: [{ op: \"replace\", path: \"\", value: [\"hello\", [\"hi\"]] }],\n },\n ];\n\n for (const patch of patches) {\n await expect(graffiti.patch(patch, putted, session)).rejects.toThrow(\n GraffitiErrorPatchError,\n );\n }\n\n const gotten = await graffiti.get(putted, {}, session);\n expect(gotten.value).toEqual(object.value);\n expect(gotten.channels).toEqual(object.channels);\n expect(gotten.allowed).toEqual(object.allowed);\n expect(gotten.lastModified).toEqual(putted.lastModified);\n });\n },\n );\n};\n", "import { it, expect, describe, assert, beforeAll } from \"vitest\";\nimport type {\n Graffiti,\n GraffitiSession,\n JSONSchema4,\n} from \"@graffiti-garden/api\";\nimport { randomString, nextStreamValue, randomPutObject } from \"./utils\";\n\nexport const graffitiDiscoverTests = (\n useGraffiti: () => Pick<Graffiti, \"discover\" | \"put\" | \"delete\" | \"patch\">,\n useSession1: () => GraffitiSession | Promise<GraffitiSession>,\n useSession2: () => GraffitiSession | Promise<GraffitiSession>,\n) => {\n describe.concurrent(\"discover\", { timeout: 20000 }, () => {\n let graffiti: ReturnType<typeof useGraffiti>;\n let session: GraffitiSession;\n let session1: GraffitiSession;\n let session2: GraffitiSession;\n beforeAll(async () => {\n graffiti = useGraffiti();\n session1 = await useSession1();\n session = session1;\n session2 = await useSession2();\n });\n\n it(\"discover nothing\", async () => {\n const iterator = graffiti.discover([], {});\n expect(await iterator.next()).toHaveProperty(\"done\", true);\n });\n\n it(\"discover single\", async () => {\n const object = randomPutObject();\n\n const putted = await graffiti.put(object, session);\n\n const queryChannels = [randomString(), object.channels[0]];\n const iterator = graffiti.discover(queryChannels, {});\n const value = await nextStreamValue(iterator);\n expect(value.value).toEqual(object.value);\n expect(value.channels).toEqual([object.channels[0]]);\n expect(value.allowed).toBeUndefined();\n expect(value.actor).toEqual(session.actor);\n expect(value.tombstone).toBe(false);\n expect(value.lastModified).toEqual(putted.lastModified);\n const result2 = await iterator.next();\n expect(result2.done).toBe(true);\n });\n\n it(\"discover wrong channel\", async () => {\n const object = randomPutObject();\n await graffiti.put(object, session);\n const iterator = graffiti.discover([randomString()], {});\n await expect(iterator.next()).resolves.toHaveProperty(\"done\", true);\n });\n\n it(\"discover not allowed\", async () => {\n const object = randomPutObject();\n object.allowed = [randomString(), randomString()];\n const putted = await graffiti.put(object, session1);\n\n const iteratorSession1 = graffiti.discover(object.channels, {}, session1);\n const value = await nextStreamValue(iteratorSession1);\n expect(value.value).toEqual(object.value);\n expect(value.channels).toEqual(object.channels);\n expect(value.allowed).toEqual(object.allowed);\n expect(value.actor).toEqual(session1.actor);\n expect(value.tombstone).toBe(false);\n expect(value.lastModified).toEqual(putted.lastModified);\n\n const iteratorSession2 = graffiti.discover(object.channels, {}, session2);\n expect(await iteratorSession2.next()).toHaveProperty(\"done\", true);\n\n const iteratorNoSession = graffiti.discover(object.channels, {});\n expect(await iteratorNoSession.next()).toHaveProperty(\"done\", true);\n });\n\n it(\"discover allowed\", async () => {\n const object = randomPutObject();\n object.allowed = [randomString(), session2.actor, randomString()];\n const putted = await graffiti.put(object, session1);\n\n const iteratorSession2 = graffiti.discover(object.channels, {}, session2);\n const value = await nextStreamValue(iteratorSession2);\n expect(value.value).toEqual(object.value);\n expect(value.allowed).toEqual([session2.actor]);\n expect(value.channels).toEqual(object.channels);\n expect(value.actor).toEqual(session1.actor);\n expect(value.tombstone).toBe(false);\n expect(value.lastModified).toEqual(putted.lastModified);\n });\n\n for (const prop of [\"name\", \"actor\", \"lastModified\"] as const) {\n it(`discover for ${prop}`, async () => {\n const object1 = randomPutObject();\n const putted1 = await graffiti.put(object1, session1);\n\n const object2 = randomPutObject();\n object2.channels = object1.channels;\n // Make sure the lastModified is different for the query\n await new Promise((r) => setTimeout(r, 20));\n const putted2 = await graffiti.put(object2, session2);\n\n const iterator = graffiti.discover(object1.channels, {\n properties: {\n [prop]: {\n enum: [putted1[prop]],\n },\n },\n });\n\n const value = await nextStreamValue(iterator);\n expect(value.name).toEqual(putted1.name);\n expect(value.name).not.toEqual(putted2.name);\n expect(value.value).toEqual(object1.value);\n await expect(iterator.next()).resolves.toHaveProperty(\"done\", true);\n });\n }\n\n it(\"discover with lastModified range\", async () => {\n const object = randomPutObject();\n const putted1 = await graffiti.put(object, session);\n // Make sure the lastModified is different\n await new Promise((r) => setTimeout(r, 20));\n const putted2 = await graffiti.put(object, session);\n\n expect(putted1.name).not.toEqual(putted2.name);\n expect(putted1.lastModified).toBeLessThan(putted2.lastModified);\n\n const gtIterator = graffiti.discover([object.channels[0]], {\n properties: {\n lastModified: {\n minimum: putted2.lastModified,\n exclusiveMinimum: true,\n },\n },\n });\n expect(await gtIterator.next()).toHaveProperty(\"done\", true);\n const gtIteratorEpsilon = graffiti.discover([object.channels[0]], {\n properties: {\n lastModified: {\n minimum: putted2.lastModified - 0.1,\n exclusiveMinimum: true,\n },\n },\n });\n const value1 = await nextStreamValue(gtIteratorEpsilon);\n expect(value1.name).toEqual(putted2.name);\n expect(await gtIteratorEpsilon.next()).toHaveProperty(\"done\", true);\n const gteIterator = graffiti.discover(object.channels, {\n properties: {\n value: {},\n lastModified: {\n minimum: putted2.lastModified,\n },\n },\n });\n const value = await nextStreamValue(gteIterator);\n expect(value.name).toEqual(putted2.name);\n expect(await gteIterator.next()).toHaveProperty(\"done\", true);\n const gteIteratorEpsilon = graffiti.discover(object.channels, {\n properties: {\n lastModified: {\n minimum: putted2.lastModified + 0.1,\n },\n },\n });\n expect(await gteIteratorEpsilon.next()).toHaveProperty(\"done\", true);\n\n const ltIterator = graffiti.discover(object.channels, {\n properties: {\n lastModified: {\n maximum: putted1.lastModified,\n exclusiveMaximum: true,\n },\n },\n });\n expect(await ltIterator.next()).toHaveProperty(\"done\", true);\n\n const ltIteratorEpsilon = graffiti.discover(object.channels, {\n properties: {\n lastModified: {\n maximum: putted1.lastModified + 0.1,\n exclusiveMaximum: true,\n },\n },\n });\n const value3 = await nextStreamValue(ltIteratorEpsilon);\n expect(value3.name).toEqual(putted1.name);\n expect(await ltIteratorEpsilon.next()).toHaveProperty(\"done\", true);\n\n const lteIterator = graffiti.discover(object.channels, {\n properties: {\n lastModified: {\n maximum: putted1.lastModified,\n },\n },\n });\n const value2 = await nextStreamValue(lteIterator);\n expect(value2.name).toEqual(putted1.name);\n expect(await lteIterator.next()).toHaveProperty(\"done\", true);\n\n const lteIteratorEpsilon = graffiti.discover(object.channels, {\n properties: {\n lastModified: {\n maximum: putted1.lastModified - 0.1,\n },\n },\n });\n expect(await lteIteratorEpsilon.next()).toHaveProperty(\"done\", true);\n });\n\n it(\"discover schema allowed, as and not as owner\", async () => {\n const object = randomPutObject();\n object.allowed = [randomString(), session2.actor, randomString()];\n await graffiti.put(object, session1);\n\n const iteratorSession1 = graffiti.discover(\n object.channels,\n {\n properties: {\n allowed: {\n minItems: 3,\n // Make sure session2.actor is in the allow list\n not: {\n items: {\n not: {\n enum: [session2.actor],\n },\n },\n },\n },\n },\n },\n session1,\n );\n const value = await nextStreamValue(iteratorSession1);\n expect(value.value).toEqual(object.value);\n await expect(iteratorSession1.next()).resolves.toHaveProperty(\n \"done\",\n true,\n );\n\n const iteratorSession2BigAllow = graffiti.discover(\n object.channels,\n {\n properties: {\n allowed: {\n minItems: 3,\n },\n },\n },\n session2,\n );\n await expect(iteratorSession2BigAllow.next()).resolves.toHaveProperty(\n \"done\",\n true,\n );\n const iteratorSession2PeekOther = graffiti.discover(\n object.channels,\n {\n properties: {\n allowed: {\n not: {\n items: {\n not: {\n enum: [object.channels[0]],\n },\n },\n },\n },\n },\n },\n session2,\n );\n await expect(iteratorSession2PeekOther.next()).resolves.toHaveProperty(\n \"done\",\n true,\n );\n const iteratorSession2SmallAllowPeekSelf = graffiti.discover(\n object.channels,\n {\n properties: {\n allowed: {\n maxItems: 1,\n not: {\n items: {\n not: {\n enum: [session2.actor],\n },\n },\n },\n },\n },\n },\n session2,\n );\n const value2 = await nextStreamValue(iteratorSession2SmallAllowPeekSelf);\n expect(value2.value).toEqual(object.value);\n await expect(\n iteratorSession2SmallAllowPeekSelf.next(),\n ).resolves.toHaveProperty(\"done\", true);\n });\n\n it(\"discover schema channels, as and not as owner\", async () => {\n const object = randomPutObject();\n object.channels = [randomString(), randomString(), randomString()];\n await graffiti.put(object, session1);\n\n const iteratorSession1 = graffiti.discover(\n [object.channels[0], object.channels[2]],\n {\n properties: {\n channels: {\n minItems: 3,\n // Make sure session2.actor is in the allow list\n not: {\n items: {\n not: {\n enum: [object.channels[1]],\n },\n },\n },\n },\n },\n },\n session1,\n );\n const value = await nextStreamValue(iteratorSession1);\n expect(value.value).toEqual(object.value);\n await expect(iteratorSession1.next()).resolves.toHaveProperty(\n \"done\",\n true,\n );\n\n const iteratorSession2BigAllow = graffiti.discover(\n [object.channels[0], object.channels[2]],\n {\n properties: {\n channels: {\n minItems: 3,\n },\n },\n },\n session2,\n );\n await expect(iteratorSession2BigAllow.next()).resolves.toHaveProperty(\n \"done\",\n true,\n );\n const iteratorSession2PeekOther = graffiti.discover(\n [object.channels[0], object.channels[2]],\n {\n properties: {\n channels: {\n not: {\n items: {\n not: {\n enum: [object.channels[1]],\n },\n },\n },\n },\n },\n },\n session2,\n );\n await expect(iteratorSession2PeekOther.next()).resolves.toHaveProperty(\n \"done\",\n true,\n );\n const iteratorSession2SmallAllowPeekSelf = graffiti.discover(\n [object.channels[0], object.channels[2]],\n {\n properties: {\n allowed: {\n maxItems: 2,\n not: {\n items: {\n not: {\n enum: [object.channels[2]],\n },\n },\n },\n },\n },\n },\n session2,\n );\n const value2 = await nextStreamValue(iteratorSession2SmallAllowPeekSelf);\n expect(value2.value).toEqual(object.value);\n await expect(\n iteratorSession2SmallAllowPeekSelf.next(),\n ).resolves.toHaveProperty(\"done\", true);\n });\n\n it(\"discover query for empty allowed\", async () => {\n const publicO = randomPutObject();\n\n const publicSchema = {\n not: {\n required: [\"allowed\"],\n },\n } satisfies JSONSchema4;\n\n await graffiti.put(publicO, session1);\n const iterator = graffiti.discover(\n publicO.channels,\n publicSchema,\n session1,\n );\n const value = await nextStreamValue(iterator);\n expect(value.value).toEqual(publicO.value);\n expect(value.allowed).toBeUndefined();\n await expect(iterator.next()).resolves.toHaveProperty(\"done\", true);\n\n const restricted = randomPutObject();\n restricted.allowed = [];\n await graffiti.put(restricted, session1);\n const iterator2 = graffiti.discover(\n restricted.channels,\n publicSchema,\n session1,\n );\n await expect(iterator2.next()).resolves.toHaveProperty(\"done\", true);\n });\n\n it(\"discover query for values\", async () => {\n const object1 = randomPutObject();\n object1.value = { test: randomString() };\n await graffiti.put(object1, session);\n\n const object2 = randomPutObject();\n object2.channels = object1.channels;\n object2.value = { test: randomString(), something: randomString() };\n await graffiti.put(object2, session);\n\n const object3 = randomPutObject();\n object3.channels = object1.channels;\n object3.value = { other: randomString(), something: randomString() };\n await graffiti.put(object3, session);\n\n const counts = new Map<string, number>();\n for (const property of [\"test\", \"something\", \"other\"] as const) {\n let count = 0;\n for await (const result of graffiti.discover(object1.channels, {\n properties: {\n value: {\n required: [property],\n },\n },\n })) {\n assert(!result.error, \"result has error\");\n if (property in result.value.value) {\n count++;\n }\n }\n counts.set(property, count);\n }\n\n expect(counts.get(\"test\")).toBe(2);\n expect(counts.get(\"something\")).toBe(2);\n expect(counts.get(\"other\")).toBe(1);\n });\n\n it(\"discover for deleted content\", async () => {\n const object = randomPutObject();\n const putted = await graffiti.put(object, session);\n const deleted = await graffiti.delete(putted, session);\n\n const iterator = graffiti.discover(object.channels, {});\n const value = await nextStreamValue(iterator);\n expect(value.tombstone).toBe(true);\n expect(value.value).toEqual(object.value);\n expect(value.channels).toEqual(object.channels);\n expect(value.actor).toEqual(session.actor);\n expect(value.lastModified).toEqual(deleted.lastModified);\n await expect(iterator.next()).resolves.toHaveProperty(\"done\", true);\n });\n\n it(\"discover for replaced channels\", async () => {\n // Do this a bunch to check for concurrency issues\n for (let i = 0; i < 10; i++) {\n const object1 = randomPutObject();\n const putted = await graffiti.put(object1, session);\n const object2 = randomPutObject();\n const replaced = await graffiti.put(\n {\n ...putted,\n ...object2,\n },\n session,\n );\n\n const iterator1 = graffiti.discover(object1.channels, {});\n const value1 = await nextStreamValue(iterator1);\n await expect(iterator1.next()).resolves.toHaveProperty(\"done\", true);\n\n const iterator2 = graffiti.discover(object2.channels, {});\n const value2 = await nextStreamValue(iterator2);\n await expect(iterator2.next()).resolves.toHaveProperty(\"done\", true);\n\n // If they have the same timestamp, except\n // only one to have a tombstone\n if (putted.lastModified === replaced.lastModified) {\n expect(value1.tombstone || value2.tombstone).toBe(true);\n expect(value1.tombstone && value2.tombstone).toBe(false);\n } else {\n expect(value1.tombstone).toBe(true);\n expect(value1.value).toEqual(object1.value);\n expect(value1.channels).toEqual(object1.channels);\n expect(value1.lastModified).toEqual(replaced.lastModified);\n\n expect(value2.tombstone).toBe(false);\n expect(value2.value).toEqual(object2.value);\n expect(value2.channels).toEqual(object2.channels);\n expect(value2.lastModified).toEqual(replaced.lastModified);\n }\n }\n });\n\n it(\"discover for patched allowed\", async () => {\n const object = randomPutObject();\n const putted = await graffiti.put(object, session);\n await graffiti.patch(\n {\n allowed: [{ op: \"add\", path: \"\", value: [] }],\n },\n putted,\n session,\n );\n const iterator = graffiti.discover(object.channels, {});\n const value = await nextStreamValue(iterator);\n expect(value.tombstone).toBe(true);\n expect(value.value).toEqual(object.value);\n expect(value.channels).toEqual(object.channels);\n expect(value.allowed).toBeUndefined();\n await expect(iterator.next()).resolves.toHaveProperty(\"done\", true);\n });\n\n it(\"put concurrently and discover one\", async () => {\n const object = randomPutObject();\n object.name = randomString();\n\n const putPromises = Array(100)\n .fill(0)\n .map(() => graffiti.put(object, session));\n await Promise.all(putPromises);\n\n const iterator = graffiti.discover(object.channels, {});\n let tombstoneCount = 0;\n let valueCount = 0;\n for await (const result of iterator) {\n assert(!result.error, \"result has error\");\n if (result.value.tombstone) {\n tombstoneCount++;\n } else {\n valueCount++;\n }\n }\n expect(tombstoneCount).toBe(99);\n expect(valueCount).toBe(1);\n });\n });\n};\n", "import { it, expect, describe, assert, beforeAll } from \"vitest\";\nimport type { Graffiti, GraffitiSession } from \"@graffiti-garden/api\";\nimport { randomPutObject, randomString } from \"./utils\";\n\nexport const graffitiOrphanTests = (\n useGraffiti: () => Pick<\n Graffiti,\n \"recoverOrphans\" | \"put\" | \"delete\" | \"patch\"\n >,\n useSession1: () => GraffitiSession | Promise<GraffitiSession>,\n useSession2: () => GraffitiSession | Promise<GraffitiSession>,\n) => {\n describe(\"recoverOrphans\", { timeout: 20000 }, () => {\n let graffiti: ReturnType<typeof useGraffiti>;\n let session: GraffitiSession;\n let session1: GraffitiSession;\n let session2: GraffitiSession;\n beforeAll(async () => {\n graffiti = useGraffiti();\n session1 = await useSession1();\n session = session1;\n session2 = await useSession2();\n });\n\n it(\"list orphans\", async () => {\n const existingOrphans: string[] = [];\n const orphanIterator1 = graffiti.recoverOrphans({}, session);\n for await (const orphan of orphanIterator1) {\n if (orphan.error) continue;\n existingOrphans.push(orphan.value.name);\n }\n\n const object = randomPutObject();\n object.channels = [];\n const putted = await graffiti.put(object, session);\n const orphanIterator2 = graffiti.recoverOrphans({}, session);\n let numResults = 0;\n for await (const orphan of orphanIterator2) {\n if (orphan.error) continue;\n if (orphan.value.name === putted.name) {\n numResults++;\n expect(orphan.value.source).toBe(putted.source);\n expect(orphan.value.lastModified).toBe(putted.lastModified);\n }\n }\n expect(numResults).toBe(1);\n });\n\n it(\"replaced orphan, no longer\", async () => {\n const object = randomPutObject();\n object.channels = [];\n const putOrphan = await graffiti.put(object, session);\n\n // Wait for the put to be processed\n await new Promise((resolve) => setTimeout(resolve, 10));\n\n const putNotOrphan = await graffiti.put(\n {\n ...putOrphan,\n ...object,\n channels: [randomString()],\n },\n session,\n );\n expect(putNotOrphan.name).toBe(putOrphan.name);\n expect(putNotOrphan.lastModified).toBeGreaterThan(putOrphan.lastModified);\n\n const orphanIterator = graffiti.recoverOrphans({}, session);\n let numResults = 0;\n for await (const orphan of orphanIterator) {\n if (orphan.error) continue;\n if (orphan.value.name === putOrphan.name) {\n numResults++;\n expect(orphan.value.tombstone).toBe(true);\n expect(orphan.value.lastModified).toBe(putNotOrphan.lastModified);\n expect(orphan.value.channels).toEqual([]);\n }\n }\n expect(numResults).toBe(1);\n });\n });\n};\n", "import { it, expect, describe, assert, beforeAll } from \"vitest\";\nimport type { Graffiti, GraffitiSession } from \"@graffiti-garden/api\";\nimport { randomString } from \"./utils\";\n\nexport const graffitiChannelStatsTests = (\n useGraffiti: () => Pick<\n Graffiti,\n \"channelStats\" | \"put\" | \"delete\" | \"patch\"\n >,\n useSession1: () => GraffitiSession | Promise<GraffitiSession>,\n useSession2: () => GraffitiSession | Promise<GraffitiSession>,\n) => {\n describe(\"channel stats\", { timeout: 20000 }, () => {\n let graffiti: ReturnType<typeof useGraffiti>;\n let session: GraffitiSession;\n let session1: GraffitiSession;\n let session2: GraffitiSession;\n beforeAll(async () => {\n graffiti = useGraffiti();\n session1 = await useSession1();\n session = session1;\n session2 = await useSession2();\n });\n\n it(\"list channels\", async () => {\n const existingChannels: Map<string, number> = new Map();\n const channelIterator1 = graffiti.channelStats(session);\n for await (const channel of channelIterator1) {\n if (channel.error) continue;\n existingChannels.set(channel.value.channel, channel.value.count);\n }\n\n const channels = [randomString(), randomString(), randomString()];\n\n // Add one value to channels[0],\n // two values to both channels[0] and channels[1],\n // three values to all channels\n // one value to channels[2]\n for (let i = 0; i < 3; i++) {\n for (let j = 0; j < i + 1; j++) {\n await graffiti.put(\n {\n value: {\n index: j,\n },\n channels: channels.slice(0, i + 1),\n },\n session,\n );\n }\n }\n await graffiti.put(\n { value: { index: 3 }, channels: [channels[2]] },\n session,\n );\n\n const channelIterator2 = graffiti.channelStats(session);\n let newChannels: Map<string, number> = new Map();\n for await (const channel of channelIterator2) {\n if (channel.error) continue;\n newChannels.set(channel.value.channel, channel.value.count);\n }\n // Filter out existing channels\n newChannels = new Map(\n Array.from(newChannels).filter(\n ([channel, count]) => !existingChannels.has(channel),\n ),\n );\n expect(newChannels.size).toBe(3);\n expect(newChannels.get(channels[0])).toBe(6);\n expect(newChannels.get(channels[1])).toBe(5);\n expect(newChannels.get(channels[2])).toBe(4);\n });\n\n it(\"list channels with deleted channel\", async () => {\n const channels = [randomString(), randomString(), randomString()];\n\n // Add an item with two channels\n const before = await graffiti.put(\n {\n value: { index: 2 },\n channels: channels.slice(1),\n },\n session,\n );\n\n // Add an item with all channels\n const first = await graffiti.put(\n { value: { index: 0 }, channels },\n session,\n );\n // But then delete it\n await graffiti.delete(first, session);\n\n // Create a new object with only one channel\n const second = await graffiti.put(\n {\n value: { index: 1 },\n channels: channels.slice(2),\n },\n session,\n );\n\n const channelIterator = graffiti.channelStats(session);\n\n let got1 = 0;\n let got2 = 0;\n for await (const result of channelIterator) {\n if (result.error) continue;\n const { channel, count, lastModified } = result.value;\n assert(\n channel !== channels[0],\n \"There should not be an object in channel[0]\",\n );\n if (channel === channels[1]) {\n expect(count).toBe(1);\n expect(lastModified).toBe(before.lastModified);\n got1++;\n } else if (channel === channels[2]) {\n expect(count).toBe(2);\n expect(lastModified).toBe(second.lastModified);\n got2++;\n }\n }\n expect(got1).toBe(1);\n expect(got2).toBe(1);\n });\n });\n};\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import { it, expect, describe } from \"vitest\";\nimport type { Graffiti } from \"@graffiti-garden/api\";\nimport { GraffitiErrorInvalidUri } from \"@graffiti-garden/api\";\nimport { randomString } from \"./utils\";\n\nexport const graffitiLocationTests = (\n useGraffiti: () => Pick<Graffiti, \"locationToUri\" | \"uriToLocation\">,\n) => {\n describe.concurrent(\"URI and location conversion\", () => {\n it(\"location to uri and back\", async () => {\n const graffiti = useGraffiti();\n const location = {\n name: randomString(),\n actor: randomString(),\n source: randomString(),\n };\n const uri = graffiti.locationToUri(location);\n const location2 = graffiti.uriToLocation(uri);\n expect(location).toEqual(location2);\n });\n\n it(\"collision resistance\", async () => {\n const graffiti = useGraffiti();\n const location1 = {\n name: randomString(),\n actor: randomString(),\n source: randomString(),\n };\n for (const prop of [\"name\", \"actor\", \"source\"] as const) {\n const location2 = { ...location1, [prop]: randomString() };\n const uri1 = graffiti.locationToUri(location1);\n const uri2 = graffiti.locationToUri(location2);\n expect(uri1).not.toEqual(uri2);\n }\n });\n\n it(\"random URI should not be a valid location\", async () => {\n const graffiti = useGraffiti();\n expect(() => graffiti.uriToLocation(\"\")).toThrow(GraffitiErrorInvalidUri);\n });\n });\n};\n", "import { assert } from \"vitest\";\nimport type { GraffitiPutObject, GraffitiStream } from \"@graffiti-garden/api\";\n\nexport function randomString(): string {\n const array = new Uint8Array(16);\n crypto.getRandomValues(array);\n const str = Array.from(array)\n .map((b) => b.toString(16).padStart(2, \"0\"))\n .join(\"\");\n\n // check for unicode support\n return str + \"\uD83D\uDC69\uD83C\uDFFD\u200D\u2764\uFE0F\u200D\uD83D\uDC8B\u200D\uD83D\uDC69\uD83C\uDFFB\uD83E\uDEF1\uD83C\uDFFC\u200D\uD83E\uDEF2\uD83C\uDFFF\";\n}\n\nexport function randomValue() {\n return {\n [randomString()]: randomString(),\n };\n}\n\nexport function randomPutObject(): GraffitiPutObject<{}> {\n return {\n value: randomValue(),\n channels: [randomString(), randomString()],\n };\n}\n\nexport async function nextStreamValue<S, T>(iterator: GraffitiStream<S, T>) {\n const result = await iterator.next();\n assert(!result.done && !result.value.error, \"result has no value\");\n return result.value.value;\n}\n", "import { it, expect, describe, beforeAll } from \"vitest\";\nimport type {\n Graffiti,\n GraffitiSession,\n GraffitiPatch,\n JSONSchema,\n} from \"@graffiti-garden/api\";\nimport type { FromSchema } from \"json-schema-to-ts\";\nimport {\n GraffitiErrorNotFound,\n GraffitiErrorSchemaMismatch,\n GraffitiErrorInvalidSchema,\n GraffitiErrorForbidden,\n GraffitiErrorPatchTestFailed,\n GraffitiErrorPatchError,\n} from \"@graffiti-garden/api\";\nimport { randomPutObject, randomString } from \"./utils\";\n\nexport const graffitiCRUDTests = (\n useGraffiti: () => Pick<Graffiti, \"put\" | \"get\" | \"delete\" | \"patch\">,\n useSession1: () => GraffitiSession | Promise<GraffitiSession>,\n useSession2: () => GraffitiSession | Promise<GraffitiSession>,\n) => {\n describe.concurrent(\n \"CRUD\",\n {\n timeout: 20000,\n },\n () => {\n let graffiti: ReturnType<typeof useGraffiti>;\n let session: GraffitiSession;\n let session1: GraffitiSession;\n let session2: GraffitiSession;\n beforeAll(async () => {\n graffiti = useGraffiti();\n session1 = await useSession1();\n session = session1;\n session2 = await useSession2();\n });\n\n it(\"put, get, delete\", async () => {\n const value = {\n something: \"hello, world~ c:\",\n };\n const channels = [randomString(), randomString()];\n\n // Put the object\n const previous = await graffiti.put<{}>({ value, channels }, session);\n expect(previous.value).toEqual({});\n expect(previous.channels).toEqual([]);\n expect(previous.allowed).toBeUndefined();\n expect(previous.actor).toEqual(session.actor);\n\n // Get it back\n const gotten = await graffiti.get(previous, {});\n expect(gotten.value).toEqual(value);\n expect(gotten.channels).toEqual([]);\n expect(gotten.allowed).toBeUndefined();\n expect(gotten.name).toEqual(previous.name);\n expect(gotten.actor).toEqual(previous.actor);\n expect(gotten.source).toEqual(previous.source);\n expect(gotten.lastModified).toEqual(previous.lastModified);\n\n // Replace it\n const newValue = {\n something: \"goodbye, world~ :c\",\n };\n const beforeReplaced = await graffiti.put<{}>(\n { ...previous, value: newValue, channels: [] },\n session,\n );\n expect(beforeReplaced.value).toEqual(value);\n expect(beforeReplaced.tombstone).toEqual(true);\n expect(beforeReplaced.name).toEqual(previous.name);\n expect(beforeReplaced.actor).toEqual(previous.actor);\n expect(beforeReplaced.source).toEqual(previous.source);\n expect(beforeReplaced.lastModified).toBeGreaterThanOrEqual(\n gotten.lastModified,\n );\n\n // Get it again\n const afterReplaced = await graffiti.get(previous, {});\n expect(afterReplaced.value).toEqual(newValue);\n expect(afterReplaced.lastModified).toEqual(beforeReplaced.lastModified);\n expect(afterReplaced.tombstone).toEqual(false);\n\n // Delete it\n const beforeDeleted = await graffiti.delete(afterReplaced, session);\n expect(beforeDeleted.tombstone).toEqual(true);\n expect(beforeDeleted.value).toEqual(newValue);\n expect(beforeDeleted.lastModified).toBeGreaterThanOrEqual(\n beforeReplaced.lastModified,\n );\n\n // Get a tombstone\n const final = await graffiti.get(afterReplaced, {});\n expect(final).toEqual(beforeDeleted);\n });\n\n it(\"get non-existant\", async () => {\n const putted = await graffiti.put<{}>(randomPutObject(), session);\n await expect(\n graffiti.get(\n {\n ...putted,\n name: randomString(),\n },\n {},\n ),\n ).rejects.toBeInstanceOf(GraffitiErrorNotFound);\n });\n\n it(\"put, get, delete with wrong actor\", async () => {\n await expect(\n graffiti.put<{}>(\n { value: {}, channels: [], actor: session2.actor },\n session1,\n ),\n ).rejects.toThrow(GraffitiErrorForbidden);\n\n const putted = await graffiti.put<{}>(\n { value: {}, channels: [] },\n session2,\n );\n\n await expect(graffiti.delete(putted, session1)).rejects.toThrow(\n GraffitiErrorForbidden,\n );\n\n await expect(graffiti.patch({}, putted, session1)).rejects.toThrow(\n GraffitiErrorForbidden,\n );\n });\n\n it(\"put and get with schema\", async () => {\n const schema = {\n properties: {\n value: {\n properties: {\n something: {\n type: \"string\",\n },\n another: {\n type: \"array\",\n items: {\n type: \"number\",\n },\n },\n deeper: {\n type: \"object\",\n properties: {\n deepProp: {\n type: \"string\",\n },\n },\n required: [\"deepProp\"],\n },\n },\n required: [\"another\", \"deeper\"],\n },\n },\n } as const satisfies JSONSchema;\n\n const goodValue = {\n something: \"hello\",\n another: [1, 2, 3],\n deeper: {\n deepProp: \"hello\",\n },\n };\n\n const putted = await graffiti.put<typeof schema>(\n {\n value: goodValue,\n channels: [],\n },\n session,\n );\n const gotten = await graffiti.get(putted, schema);\n\n expect(gotten.value.something).toEqual(goodValue.something);\n expect(gotten.value.another).toEqual(goodValue.another);\n expect(gotten.value.another[0]).toEqual(1);\n expect(gotten.value.deeper.deepProp).toEqual(goodValue.deeper.deepProp);\n });\n\n it(\"put and get with invalid schema\", async () => {\n const putted = await graffiti.put<{}>(\n { value: {}, channels: [] },\n session,\n );\n await expect(\n graffiti.get(putted, {\n properties: {\n value: {\n //@ts-ignore\n type: \"asdf\",\n },\n },\n }),\n ).rejects.toThrow(GraffitiErrorInvalidSchema);\n });\n\n it(\"put and get with wrong schema\", async () => {\n const putted = await graffiti.put<{}>(\n {\n value: {\n hello: \"world\",\n },\n channels: [],\n },\n session,\n );\n\n await expect(\n graffiti.get(putted, {\n properties: {\n value: {\n properties: {\n hello: {\n type: \"number\",\n },\n },\n },\n },\n }),\n ).rejects.toThrow(GraffitiErrorSchemaMismatch);\n });\n\n it(\"put and get with empty access control\", async () => {\n const value = {\n um: \"hi\",\n };\n const allowed = [randomString()];\n const channels = [randomString()];\n const putted = await graffiti.put<{}>(\n { value, allowed, channels },\n session1,\n );\n\n // Get it with authenticated session\n const gotten = await graffiti.get(putted, {}, session1);\n expect(gotten.value).toEqual(value);\n expect(gotten.allowed).toEqual(allowed);\n expect(gotten.channels).toEqual(channels);\n\n // But not without session\n await expect(graffiti.get(putted, {})).rejects.toBeInstanceOf(\n GraffitiErrorNotFound,\n );\n\n // Or the wrong session\n await expect(graffiti.get(putted, {}, session2)).rejects.toBeInstanceOf(\n GraffitiErrorNotFound,\n );\n });\n\n it(\"put and get with specific access control\", async () => {\n const value = {\n um: \"hi\",\n };\n const allowed = [randomString(), session2.actor, randomString()];\n const channels = [randomString()];\n const putted = await graffiti.put<{}>(\n {\n value,\n allowed,\n channels,\n },\n session1,\n );\n\n // Get it with authenticated session\n const gotten = await graffiti.get(putted, {}, session1);\n expect(gotten.value).toEqual(value);\n expect(gotten.allowed).toEqual(allowed);\n expect(gotten.channels).toEqual(channels);\n\n // But not without session\n await expect(graffiti.get(putted, {})).rejects.toBeInstanceOf(\n GraffitiErrorNotFound,\n );\n\n const gotten2 = await graffiti.get(putted, {}, session2);\n expect(gotten2.value).toEqual(value);\n // They should only see that is is private to them\n expect(gotten2.allowed).toEqual([session2.actor]);\n // And not see any channels\n expect(gotten2.channels).toEqual([]);\n });\n\n it(\"patch value\", async () => {\n const value = {\n something: \"hello, world~ c:\",\n };\n const putted = await graffiti.put<{}>({ value, channels: [] }, session);\n\n // Wait just a bit to make sure the lastModified is different\n await new Promise((resolve) => setTimeout(resolve, 10));\n\n const patch: GraffitiPatch = {\n value: [\n { op: \"replace\", path: \"/something\", value: \"goodbye, world~ :c\" },\n ],\n };\n const beforePatched = await graffiti.patch(patch, putted, session);\n expect(beforePatched.value).toEqual(value);\n expect(beforePatched.tombstone).toBe(true);\n expect(beforePatched.lastModified).toBeGreaterThan(putted.lastModified);\n\n const gotten = await graffiti.get(putted, {});\n expect(gotten.value).toEqual({\n something: \"goodbye, world~ :c\",\n });\n expect(beforePatched.lastModified).toBe(gotten.lastModified);\n\n await graffiti.delete(putted, session);\n });\n\n it(\"patch deleted object\", async () => {\n const putted = await graffiti.put<{}>(randomPutObject(), session);\n const deleted = await graffiti.delete(putted, session);\n await expect(\n graffiti.patch({}, putted, session),\n ).rejects.toBeInstanceOf(GraffitiErrorNotFound);\n });\n\n it(\"deep patch\", async () => {\n const value = {\n something: {\n another: {\n somethingElse: \"hello\",\n },\n },\n };\n const putted = await graffiti.put<{}>(\n { value: value, channels: [] },\n session,\n );\n\n const beforePatch = await graffiti.patch(\n {\n value: [\n {\n op: \"replace\",\n path: \"/something/another/somethingElse\",\n value: \"goodbye\",\n },\n ],\n },\n putted,\n session,\n );\n const gotten = await graffiti.get(putted, {});\n\n expect(beforePatch.value).toEqual(value);\n expect(gotten.value).toEqual({\n something: {\n another: {\n somethingElse: \"goodbye\",\n },\n },\n });\n });\n\n it(\"patch channels\", async () => {\n const channelsBefore = [randomString()];\n const channelsAfter = [randomString()];\n\n const putted = await graffiti.put<{}>(\n { value: {}, channels: channelsBefore },\n session,\n );\n\n const patch: GraffitiPatch = {\n channels: [{ op: \"replace\", path: \"/0\", value: channelsAfter[0] }],\n };\n const patched = await graffiti.patch(patch, putted, session);\n expect(patched.channels).toEqual(channelsBefore);\n const gotten = await graffiti.get(putted, {}, session);\n expect(gotten.channels).toEqual(channelsAfter);\n await graffiti.delete(putted, session);\n });\n\n it(\"patch 'increment' with test\", async () => {\n const putted = await graffiti.put<{}>(\n {\n value: {\n counter: 1,\n },\n channels: [],\n },\n session,\n );\n\n const previous = await graffiti.patch(\n {\n value: [\n { op: \"test\", path: \"/counter\", value: 1 },\n { op: \"replace\", path: \"/counter\", value: 2 },\n ],\n },\n putted,\n session,\n );\n expect(previous.value).toEqual({ counter: 1 });\n const result = await graffiti.get(previous, {\n properties: {\n value: {\n properties: {\n counter: {\n type: \"integer\",\n },\n },\n },\n },\n });\n expect(result.value.counter).toEqual(2);\n\n await expect(\n graffiti.patch(\n {\n value: [\n { op: \"test\", path: \"/counter\", value: 1 },\n { op: \"replace\", path: \"/counter\", value: 3 },\n ],\n },\n putted,\n session,\n ),\n ).rejects.toThrow(GraffitiErrorPatchTestFailed);\n });\n\n it(\"invalid patch\", async () => {\n const object = randomPutObject();\n const putted = await graffiti.put<{}>(object, session);\n\n await expect(\n graffiti.patch(\n {\n value: [\n { op: \"add\", path: \"/root\", value: [] },\n { op: \"add\", path: \"/root/2\", value: 2 }, // out of bounds\n ],\n },\n putted,\n session,\n ),\n ).rejects.toThrow(GraffitiErrorPatchError);\n });\n\n it(\"patch channels to be wrong\", async () => {\n const object = randomPutObject();\n object.allowed = [randomString()];\n const putted = await graffiti.put<{}>(object, session);\n\n const patches: GraffitiPatch[] = [\n {\n channels: [{ op: \"replace\", path: \"\", value: null }],\n },\n {\n channels: [{ op: \"replace\", path: \"\", value: {} }],\n },\n {\n channels: [{ op: \"replace\", path: \"\", value: [\"hello\", [\"hi\"]] }],\n },\n {\n channels: [{ op: \"add\", path: \"/0\", value: 1 }],\n },\n {\n value: [{ op: \"replace\", path: \"\", value: \"not an object\" }],\n },\n {\n value: [{ op: \"replace\", path: \"\", value: null }],\n },\n {\n value: [{ op: \"replace\", path: \"\", value: [] }],\n },\n {\n allowed: [{ op: \"replace\", path: \"\", value: {} }],\n },\n {\n allowed: [{ op: \"replace\", path: \"\", value: [\"hello\", [\"hi\"]] }],\n },\n ];\n\n for (const patch of patches) {\n await expect(graffiti.patch(patch, putted, session)).rejects.toThrow(\n GraffitiErrorPatchError,\n );\n }\n\n const gotten = await graffiti.get(putted, {}, session);\n expect(gotten.value).toEqual(object.value);\n expect(gotten.channels).toEqual(object.channels);\n expect(gotten.allowed).toEqual(object.allowed);\n expect(gotten.lastModified).toEqual(putted.lastModified);\n });\n },\n );\n};\n", "import { it, expect, describe, assert, beforeAll } from \"vitest\";\nimport type {\n Graffiti,\n GraffitiSession,\n JSONSchema,\n} from \"@graffiti-garden/api\";\nimport { randomString, nextStreamValue, randomPutObject } from \"./utils\";\n\nexport const graffitiDiscoverTests = (\n useGraffiti: () => Pick<Graffiti, \"discover\" | \"put\" | \"delete\" | \"patch\">,\n useSession1: () => GraffitiSession | Promise<GraffitiSession>,\n useSession2: () => GraffitiSession | Promise<GraffitiSession>,\n) => {\n describe.concurrent(\"discover\", { timeout: 20000 }, () => {\n let graffiti: ReturnType<typeof useGraffiti>;\n let session: GraffitiSession;\n let session1: GraffitiSession;\n let session2: GraffitiSession;\n beforeAll(async () => {\n graffiti = useGraffiti();\n session1 = await useSession1();\n session = session1;\n session2 = await useSession2();\n });\n\n it(\"discover nothing\", async () => {\n const iterator = graffiti.discover([], {});\n expect(await iterator.next()).toHaveProperty(\"done\", true);\n });\n\n it(\"discover single\", async () => {\n const object = randomPutObject();\n\n const putted = await graffiti.put<{}>(object, session);\n\n const queryChannels = [randomString(), object.channels[0]];\n const iterator = graffiti.discover(queryChannels, {});\n const value = await nextStreamValue(iterator);\n expect(value.value).toEqual(object.value);\n expect(value.channels).toEqual([object.channels[0]]);\n expect(value.allowed).toBeUndefined();\n expect(value.actor).toEqual(session.actor);\n expect(value.tombstone).toBe(false);\n expect(value.lastModified).toEqual(putted.lastModified);\n const result2 = await iterator.next();\n expect(result2.done).toBe(true);\n });\n\n it(\"discover wrong channel\", async () => {\n const object = randomPutObject();\n await graffiti.put<{}>(object, session);\n const iterator = graffiti.discover([randomString()], {});\n await expect(iterator.next()).resolves.toHaveProperty(\"done\", true);\n });\n\n it(\"discover not allowed\", async () => {\n const object = randomPutObject();\n object.allowed = [randomString(), randomString()];\n const putted = await graffiti.put<{}>(object, session1);\n\n const iteratorSession1 = graffiti.discover(object.channels, {}, session1);\n const value = await nextStreamValue(iteratorSession1);\n expect(value.value).toEqual(object.value);\n expect(value.channels).toEqual(object.channels);\n expect(value.allowed).toEqual(object.allowed);\n expect(value.actor).toEqual(session1.actor);\n expect(value.tombstone).toBe(false);\n expect(value.lastModified).toEqual(putted.lastModified);\n\n const iteratorSession2 = graffiti.discover(object.channels, {}, session2);\n expect(await iteratorSession2.next()).toHaveProperty(\"done\", true);\n\n const iteratorNoSession = graffiti.discover(object.channels, {});\n expect(await iteratorNoSession.next()).toHaveProperty(\"done\", true);\n });\n\n it(\"discover allowed\", async () => {\n const object = randomPutObject();\n object.allowed = [randomString(), session2.actor, randomString()];\n const putted = await graffiti.put<{}>(object, session1);\n\n const iteratorSession2 = graffiti.discover(object.channels, {}, session2);\n const value = await nextStreamValue(iteratorSession2);\n expect(value.value).toEqual(object.value);\n expect(value.allowed).toEqual([session2.actor]);\n expect(value.channels).toEqual(object.channels);\n expect(value.actor).toEqual(session1.actor);\n expect(value.tombstone).toBe(false);\n expect(value.lastModified).toEqual(putted.lastModified);\n });\n\n for (const prop of [\"name\", \"actor\", \"lastModified\"] as const) {\n it(`discover for ${prop}`, async () => {\n const object1 = randomPutObject();\n const putted1 = await graffiti.put<{}>(object1, session1);\n\n const object2 = randomPutObject();\n object2.channels = object1.channels;\n // Make sure the lastModified is different for the query\n await new Promise((r) => setTimeout(r, 20));\n const putted2 = await graffiti.put<{}>(object2, session2);\n\n const iterator = graffiti.discover(object1.channels, {\n properties: {\n [prop]: {\n enum: [putted1[prop]],\n },\n },\n });\n\n const value = await nextStreamValue(iterator);\n expect(value.name).toEqual(putted1.name);\n expect(value.name).not.toEqual(putted2.name);\n expect(value.value).toEqual(object1.value);\n await expect(iterator.next()).resolves.toHaveProperty(\"done\", true);\n });\n }\n\n it(\"discover with lastModified range\", async () => {\n const object = randomPutObject();\n const putted1 = await graffiti.put<{}>(object, session);\n // Make sure the lastModified is different\n await new Promise((r) => setTimeout(r, 20));\n const putted2 = await graffiti.put<{}>(object, session);\n\n expect(putted1.name).not.toEqual(putted2.name);\n expect(putted1.lastModified).toBeLessThan(putted2.lastModified);\n\n const gtIterator = graffiti.discover([object.channels[0]], {\n properties: {\n lastModified: {\n exclusiveMinimum: putted2.lastModified,\n },\n },\n });\n expect(await gtIterator.next()).toHaveProperty(\"done\", true);\n const gtIteratorEpsilon = graffiti.discover([object.channels[0]], {\n properties: {\n lastModified: {\n exclusiveMinimum: putted2.lastModified - 0.1,\n },\n },\n });\n const value1 = await nextStreamValue(gtIteratorEpsilon);\n expect(value1.name).toEqual(putted2.name);\n expect(await gtIteratorEpsilon.next()).toHaveProperty(\"done\", true);\n const gteIterator = graffiti.discover(object.channels, {\n properties: {\n value: {},\n lastModified: {\n minimum: putted2.lastModified,\n },\n },\n });\n const value = await nextStreamValue(gteIterator);\n expect(value.name).toEqual(putted2.name);\n expect(await gteIterator.next()).toHaveProperty(\"done\", true);\n const gteIteratorEpsilon = graffiti.discover(object.channels, {\n properties: {\n lastModified: {\n minimum: putted2.lastModified + 0.1,\n },\n },\n });\n expect(await gteIteratorEpsilon.next()).toHaveProperty(\"done\", true);\n\n const ltIterator = graffiti.discover(object.channels, {\n properties: {\n lastModified: {\n exclusiveMaximum: putted1.lastModified,\n },\n },\n });\n expect(await ltIterator.next()).toHaveProperty(\"done\", true);\n\n const ltIteratorEpsilon = graffiti.discover(object.channels, {\n properties: {\n lastModified: {\n exclusiveMaximum: putted1.lastModified + 0.1,\n },\n },\n });\n const value3 = await nextStreamValue(ltIteratorEpsilon);\n expect(value3.name).toEqual(putted1.name);\n expect(await ltIteratorEpsilon.next()).toHaveProperty(\"done\", true);\n\n const lteIterator = graffiti.discover(object.channels, {\n properties: {\n lastModified: {\n maximum: putted1.lastModified,\n },\n },\n });\n const value2 = await nextStreamValue(lteIterator);\n expect(value2.name).toEqual(putted1.name);\n expect(await lteIterator.next()).toHaveProperty(\"done\", true);\n\n const lteIteratorEpsilon = graffiti.discover(object.channels, {\n properties: {\n lastModified: {\n maximum: putted1.lastModified - 0.1,\n },\n },\n });\n expect(await lteIteratorEpsilon.next()).toHaveProperty(\"done\", true);\n });\n\n it(\"discover schema allowed, as and not as owner\", async () => {\n const object = randomPutObject();\n object.allowed = [randomString(), session2.actor, randomString()];\n await graffiti.put<{}>(object, session1);\n\n const iteratorSession1 = graffiti.discover(\n object.channels,\n {\n properties: {\n allowed: {\n minItems: 3,\n // Make sure session2.actor is in the allow list\n not: {\n items: {\n not: {\n enum: [session2.actor],\n },\n },\n },\n },\n },\n },\n session1,\n );\n const value = await nextStreamValue(iteratorSession1);\n expect(value.value).toEqual(object.value);\n await expect(iteratorSession1.next()).resolves.toHaveProperty(\n \"done\",\n true,\n );\n\n const iteratorSession2BigAllow = graffiti.discover(\n object.channels,\n {\n properties: {\n allowed: {\n minItems: 3,\n },\n },\n },\n session2,\n );\n await expect(iteratorSession2BigAllow.next()).resolves.toHaveProperty(\n \"done\",\n true,\n );\n const iteratorSession2PeekOther = graffiti.discover(\n object.channels,\n {\n properties: {\n allowed: {\n not: {\n items: {\n not: {\n enum: [object.channels[0]],\n },\n },\n },\n },\n },\n },\n session2,\n );\n await expect(iteratorSession2PeekOther.next()).resolves.toHaveProperty(\n \"done\",\n true,\n );\n const iteratorSession2SmallAllowPeekSelf = graffiti.discover(\n object.channels,\n {\n properties: {\n allowed: {\n maxItems: 1,\n not: {\n items: {\n not: {\n enum: [session2.actor],\n },\n },\n },\n },\n },\n },\n session2,\n );\n const value2 = await nextStreamValue(iteratorSession2SmallAllowPeekSelf);\n expect(value2.value).toEqual(object.value);\n await expect(\n iteratorSession2SmallAllowPeekSelf.next(),\n ).resolves.toHaveProperty(\"done\", true);\n });\n\n it(\"discover schema channels, as and not as owner\", async () => {\n const object = randomPutObject();\n object.channels = [randomString(), randomString(), randomString()];\n await graffiti.put<{}>(object, session1);\n\n const iteratorSession1 = graffiti.discover(\n [object.channels[0], object.channels[2]],\n {\n properties: {\n channels: {\n minItems: 3,\n // Make sure session2.actor is in the allow list\n not: {\n items: {\n not: {\n enum: [object.channels[1]],\n },\n },\n },\n },\n },\n },\n session1,\n );\n const value = await nextStreamValue(iteratorSession1);\n expect(value.value).toEqual(object.value);\n await expect(iteratorSession1.next()).resolves.toHaveProperty(\n \"done\",\n true,\n );\n\n const iteratorSession2BigAllow = graffiti.discover(\n [object.channels[0], object.channels[2]],\n {\n properties: {\n channels: {\n minItems: 3,\n },\n },\n },\n session2,\n );\n await expect(iteratorSession2BigAllow.next()).resolves.toHaveProperty(\n \"done\",\n true,\n );\n const iteratorSession2PeekOther = graffiti.discover(\n [object.channels[0], object.channels[2]],\n {\n properties: {\n channels: {\n not: {\n items: {\n not: {\n enum: [object.channels[1]],\n },\n },\n },\n },\n },\n },\n session2,\n );\n await expect(iteratorSession2PeekOther.next()).resolves.toHaveProperty(\n \"done\",\n true,\n );\n const iteratorSession2SmallAllowPeekSelf = graffiti.discover(\n [object.channels[0], object.channels[2]],\n {\n properties: {\n allowed: {\n maxItems: 2,\n not: {\n items: {\n not: {\n enum: [object.channels[2]],\n },\n },\n },\n },\n },\n },\n session2,\n );\n const value2 = await nextStreamValue(iteratorSession2SmallAllowPeekSelf);\n expect(value2.value).toEqual(object.value);\n await expect(\n iteratorSession2SmallAllowPeekSelf.next(),\n ).resolves.toHaveProperty(\"done\", true);\n });\n\n it(\"discover query for empty allowed\", async () => {\n const publicO = randomPutObject();\n\n const publicSchema = {\n not: {\n required: [\"allowed\"],\n },\n } satisfies JSONSchema;\n\n await graffiti.put<{}>(publicO, session1);\n const iterator = graffiti.discover(\n publicO.channels,\n publicSchema,\n session1,\n );\n const value = await nextStreamValue(iterator);\n expect(value.value).toEqual(publicO.value);\n expect(value.allowed).toBeUndefined();\n await expect(iterator.next()).resolves.toHaveProperty(\"done\", true);\n\n const restricted = randomPutObject();\n restricted.allowed = [];\n await graffiti.put<{}>(restricted, session1);\n const iterator2 = graffiti.discover(\n restricted.channels,\n publicSchema,\n session1,\n );\n await expect(iterator2.next()).resolves.toHaveProperty(\"done\", true);\n });\n\n it(\"discover query for values\", async () => {\n const object1 = randomPutObject();\n object1.value = { test: randomString() };\n await graffiti.put<{}>(object1, session);\n\n const object2 = randomPutObject();\n object2.channels = object1.channels;\n object2.value = { test: randomString(), something: randomString() };\n await graffiti.put<{}>(object2, session);\n\n const object3 = randomPutObject();\n object3.channels = object1.channels;\n object3.value = { other: randomString(), something: randomString() };\n await graffiti.put<{}>(object3, session);\n\n const counts = new Map<string, number>();\n for (const property of [\"test\", \"something\", \"other\"] as const) {\n let count = 0;\n for await (const result of graffiti.discover(object1.channels, {\n properties: {\n value: {\n required: [property],\n },\n },\n })) {\n assert(!result.error, \"result has error\");\n if (property in result.value.value) {\n count++;\n }\n }\n counts.set(property, count);\n }\n\n expect(counts.get(\"test\")).toBe(2);\n expect(counts.get(\"something\")).toBe(2);\n expect(counts.get(\"other\")).toBe(1);\n });\n\n it(\"discover for deleted content\", async () => {\n const object = randomPutObject();\n const putted = await graffiti.put<{}>(object, session);\n const deleted = await graffiti.delete(putted, session);\n\n const iterator = graffiti.discover(object.channels, {});\n const value = await nextStreamValue(iterator);\n expect(value.tombstone).toBe(true);\n expect(value.value).toEqual(object.value);\n expect(value.channels).toEqual(object.channels);\n expect(value.actor).toEqual(session.actor);\n expect(value.lastModified).toEqual(deleted.lastModified);\n await expect(iterator.next()).resolves.toHaveProperty(\"done\", true);\n });\n\n it(\"discover for replaced channels\", async () => {\n // Do this a bunch to check for concurrency issues\n for (let i = 0; i < 10; i++) {\n const object1 = randomPutObject();\n const putted = await graffiti.put<{}>(object1, session);\n const object2 = randomPutObject();\n const replaced = await graffiti.put<{}>(\n {\n ...putted,\n ...object2,\n },\n session,\n );\n\n const iterator1 = graffiti.discover(object1.channels, {});\n const value1 = await nextStreamValue(iterator1);\n await expect(iterator1.next()).resolves.toHaveProperty(\"done\", true);\n\n const iterator2 = graffiti.discover(object2.channels, {});\n const value2 = await nextStreamValue(iterator2);\n await expect(iterator2.next()).resolves.toHaveProperty(\"done\", true);\n\n // If they have the same timestamp, except\n // only one to have a tombstone\n if (putted.lastModified === replaced.lastModified) {\n expect(value1.tombstone || value2.tombstone).toBe(true);\n expect(value1.tombstone && value2.tombstone).toBe(false);\n } else {\n expect(value1.tombstone).toBe(true);\n expect(value1.value).toEqual(object1.value);\n expect(value1.channels).toEqual(object1.channels);\n expect(value1.lastModified).toEqual(replaced.lastModified);\n\n expect(value2.tombstone).toBe(false);\n expect(value2.value).toEqual(object2.value);\n expect(value2.channels).toEqual(object2.channels);\n expect(value2.lastModified).toEqual(replaced.lastModified);\n }\n }\n });\n\n it(\"discover for patched allowed\", async () => {\n const object = randomPutObject();\n const putted = await graffiti.put<{}>(object, session);\n await graffiti.patch(\n {\n allowed: [{ op: \"add\", path: \"\", value: [] }],\n },\n putted,\n session,\n );\n const iterator = graffiti.discover(object.channels, {});\n const value = await nextStreamValue(iterator);\n expect(value.tombstone).toBe(true);\n expect(value.value).toEqual(object.value);\n expect(value.channels).toEqual(object.channels);\n expect(value.allowed).toBeUndefined();\n await expect(iterator.next()).resolves.toHaveProperty(\"done\", true);\n });\n\n it(\"put concurrently and discover one\", async () => {\n const object = randomPutObject();\n object.name = randomString();\n\n const putPromises = Array(100)\n .fill(0)\n .map(() => graffiti.put<{}>(object, session));\n await Promise.all(putPromises);\n\n const iterator = graffiti.discover(object.channels, {});\n let tombstoneCount = 0;\n let valueCount = 0;\n for await (const result of iterator) {\n assert(!result.error, \"result has error\");\n if (result.value.tombstone) {\n tombstoneCount++;\n } else {\n valueCount++;\n }\n }\n expect(tombstoneCount).toBe(99);\n expect(valueCount).toBe(1);\n });\n });\n};\n", "import { it, expect, describe, assert, beforeAll } from \"vitest\";\nimport type { Graffiti, GraffitiSession } from \"@graffiti-garden/api\";\nimport { randomPutObject, randomString } from \"./utils\";\n\nexport const graffitiOrphanTests = (\n useGraffiti: () => Pick<\n Graffiti,\n \"recoverOrphans\" | \"put\" | \"delete\" | \"patch\"\n >,\n useSession1: () => GraffitiSession | Promise<GraffitiSession>,\n useSession2: () => GraffitiSession | Promise<GraffitiSession>,\n) => {\n describe(\"recoverOrphans\", { timeout: 20000 }, () => {\n let graffiti: ReturnType<typeof useGraffiti>;\n let session: GraffitiSession;\n let session1: GraffitiSession;\n let session2: GraffitiSession;\n beforeAll(async () => {\n graffiti = useGraffiti();\n session1 = await useSession1();\n session = session1;\n session2 = await useSession2();\n });\n\n it(\"list orphans\", async () => {\n const existingOrphans: string[] = [];\n const orphanIterator1 = graffiti.recoverOrphans({}, session);\n for await (const orphan of orphanIterator1) {\n if (orphan.error) continue;\n existingOrphans.push(orphan.value.name);\n }\n\n const object = randomPutObject();\n object.channels = [];\n const putted = await graffiti.put<{}>(object, session);\n const orphanIterator2 = graffiti.recoverOrphans({}, session);\n let numResults = 0;\n for await (const orphan of orphanIterator2) {\n if (orphan.error) continue;\n if (orphan.value.name === putted.name) {\n numResults++;\n expect(orphan.value.source).toBe(putted.source);\n expect(orphan.value.lastModified).toBe(putted.lastModified);\n }\n }\n expect(numResults).toBe(1);\n });\n\n it(\"replaced orphan, no longer\", async () => {\n const object = randomPutObject();\n object.channels = [];\n const putOrphan = await graffiti.put<{}>(object, session);\n\n // Wait for the put to be processed\n await new Promise((resolve) => setTimeout(resolve, 10));\n\n const putNotOrphan = await graffiti.put<{}>(\n {\n ...putOrphan,\n ...object,\n channels: [randomString()],\n },\n session,\n );\n expect(putNotOrphan.name).toBe(putOrphan.name);\n expect(putNotOrphan.lastModified).toBeGreaterThan(putOrphan.lastModified);\n\n const orphanIterator = graffiti.recoverOrphans({}, session);\n let numResults = 0;\n for await (const orphan of orphanIterator) {\n if (orphan.error) continue;\n if (orphan.value.name === putOrphan.name) {\n numResults++;\n expect(orphan.value.tombstone).toBe(true);\n expect(orphan.value.lastModified).toBe(putNotOrphan.lastModified);\n expect(orphan.value.channels).toEqual([]);\n }\n }\n expect(numResults).toBe(1);\n });\n });\n};\n", "import { it, expect, describe, assert, beforeAll } from \"vitest\";\nimport type { Graffiti, GraffitiSession } from \"@graffiti-garden/api\";\nimport { randomString } from \"./utils\";\n\nexport const graffitiChannelStatsTests = (\n useGraffiti: () => Pick<\n Graffiti,\n \"channelStats\" | \"put\" | \"delete\" | \"patch\"\n >,\n useSession1: () => GraffitiSession | Promise<GraffitiSession>,\n useSession2: () => GraffitiSession | Promise<GraffitiSession>,\n) => {\n describe(\"channel stats\", { timeout: 20000 }, () => {\n let graffiti: ReturnType<typeof useGraffiti>;\n let session: GraffitiSession;\n let session1: GraffitiSession;\n let session2: GraffitiSession;\n beforeAll(async () => {\n graffiti = useGraffiti();\n session1 = await useSession1();\n session = session1;\n session2 = await useSession2();\n });\n\n it(\"list channels\", async () => {\n const existingChannels: Map<string, number> = new Map();\n const channelIterator1 = graffiti.channelStats(session);\n for await (const channel of channelIterator1) {\n if (channel.error) continue;\n existingChannels.set(channel.value.channel, channel.value.count);\n }\n\n const channels = [randomString(), randomString(), randomString()];\n\n // Add one value to channels[0],\n // two values to both channels[0] and channels[1],\n // three values to all channels\n // one value to channels[2]\n for (let i = 0; i < 3; i++) {\n for (let j = 0; j < i + 1; j++) {\n await graffiti.put<{}>(\n {\n value: {\n index: j,\n },\n channels: channels.slice(0, i + 1),\n },\n session,\n );\n }\n }\n await graffiti.put<{}>(\n { value: { index: 3 }, channels: [channels[2]] },\n session,\n );\n\n const channelIterator2 = graffiti.channelStats(session);\n let newChannels: Map<string, number> = new Map();\n for await (const channel of channelIterator2) {\n if (channel.error) continue;\n newChannels.set(channel.value.channel, channel.value.count);\n }\n // Filter out existing channels\n newChannels = new Map(\n Array.from(newChannels).filter(\n ([channel, count]) => !existingChannels.has(channel),\n ),\n );\n expect(newChannels.size).toBe(3);\n expect(newChannels.get(channels[0])).toBe(6);\n expect(newChannels.get(channels[1])).toBe(5);\n expect(newChannels.get(channels[2])).toBe(4);\n });\n\n it(\"list channels with deleted channel\", async () => {\n const channels = [randomString(), randomString(), randomString()];\n\n // Add an item with two channels\n const before = await graffiti.put<{}>(\n {\n value: { index: 2 },\n channels: channels.slice(1),\n },\n session,\n );\n\n // Add an item with all channels\n const first = await graffiti.put<{}>(\n { value: { index: 0 }, channels },\n session,\n );\n // But then delete it\n await graffiti.delete(first, session);\n\n // Create a new object with only one channel\n const second = await graffiti.put<{}>(\n {\n value: { index: 1 },\n channels: channels.slice(2),\n },\n session,\n );\n\n const channelIterator = graffiti.channelStats(session);\n\n let got1 = 0;\n let got2 = 0;\n for await (const result of channelIterator) {\n if (result.error) continue;\n const { channel, count, lastModified } = result.value;\n assert(\n channel !== channels[0],\n \"There should not be an object in channel[0]\",\n );\n if (channel === channels[1]) {\n expect(count).toBe(1);\n expect(lastModified).toBe(before.lastModified);\n got1++;\n } else if (channel === channels[2]) {\n expect(count).toBe(2);\n expect(lastModified).toBe(second.lastModified);\n got2++;\n }\n }\n expect(got1).toBe(1);\n expect(got2).toBe(1);\n });\n });\n};\n"],
5
+ "mappings": "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",
6
6
  "names": ["it", "expect", "describe", "describe", "it", "expect", "it", "expect", "describe", "assert", "beforeAll", "describe", "beforeAll", "it", "expect", "assert", "it", "expect", "describe", "beforeAll", "describe", "beforeAll", "it", "expect", "it", "expect", "describe", "assert", "beforeAll", "describe", "beforeAll", "it", "expect", "assert"]
7
7
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@graffiti-garden/api",
3
- "version": "0.3.0",
3
+ "version": "0.4.0",
4
4
  "description": "The heart of Graffiti",
5
5
  "types": "./dist/src/index.d.ts",
6
6
  "module": "./dist/index.mjs",
@@ -55,8 +55,7 @@
55
55
  "vitest": "^2.1.9"
56
56
  },
57
57
  "dependencies": {
58
- "@types/json-schema": "^7.0.15",
59
- "ajv": "^8.17.1",
60
- "fast-json-patch": "^3.1.1"
58
+ "fast-json-patch": "^3.1.1",
59
+ "json-schema-to-ts": "^3.1.1"
61
60
  }
62
61
  }
package/src/1-api.ts CHANGED
@@ -8,7 +8,7 @@ import type {
8
8
  GraffitiStream,
9
9
  ChannelStats,
10
10
  } from "./2-types";
11
- import type { JSONSchema4 } from "json-schema";
11
+ import type { JSONSchema } from "json-schema-to-ts";
12
12
 
13
13
  /**
14
14
  * This API describes a small but powerful set of methods that
@@ -239,7 +239,7 @@ export abstract class Graffiti {
239
239
  *
240
240
  * @group CRUD Methods
241
241
  */
242
- abstract put<Schema>(
242
+ abstract put<Schema extends JSONSchema>(
243
243
  /**
244
244
  * The object to be put. This object is statically type-checked against the [JSON schema](https://json-schema.org/) that can be optionally provided
245
245
  * as the generic type parameter. We highly recommend providing a schema to
@@ -278,7 +278,7 @@ export abstract class Graffiti {
278
278
  *
279
279
  * @group CRUD Methods
280
280
  */
281
- abstract get<Schema extends JSONSchema4>(
281
+ abstract get<Schema extends JSONSchema>(
282
282
  /**
283
283
  * The location of the object to get.
284
284
  */
@@ -415,7 +415,7 @@ export abstract class Graffiti {
415
415
  *
416
416
  * @group Query Methods
417
417
  */
418
- abstract discover<Schema extends JSONSchema4>(
418
+ abstract discover<Schema extends JSONSchema>(
419
419
  /**
420
420
  * The {@link GraffitiObjectBase.channels | `channels`} that objects must be associated with.
421
421
  */
@@ -453,7 +453,7 @@ export abstract class Graffiti {
453
453
  *
454
454
  * @group Query Methods
455
455
  */
456
- abstract recoverOrphans<Schema extends JSONSchema4>(
456
+ abstract recoverOrphans<Schema extends JSONSchema>(
457
457
  /**
458
458
  * A [JSON Schema](https://json-schema.org) that orphaned objects must satisfy.
459
459
  */
package/src/2-types.ts CHANGED
@@ -1,4 +1,4 @@
1
- import type { JTDDataType } from "ajv/dist/core";
1
+ import type { JSONSchema, FromSchema } from "json-schema-to-ts";
2
2
  import type { Operation as JSONPatchOperation } from "fast-json-patch";
3
3
 
4
4
  /**
@@ -121,7 +121,36 @@ export interface GraffitiObjectBase {
121
121
  *
122
122
  * Schema-aware objects are returned by {@link Graffiti.get} and {@link Graffiti.discover}.
123
123
  */
124
- export type GraffitiObject<Schema> = GraffitiObjectBase & JTDDataType<Schema>;
124
+ export type GraffitiObject<Schema extends JSONSchema> = GraffitiObjectBase &
125
+ FromSchema<Schema & typeof GraffitiObjectJSONSchema>;
126
+
127
+ /**
128
+ * A JSON Schema equivalent to the {@link GraffitiObjectBase} type.
129
+ * Needed internally for type inference of JSON Schemas, but can
130
+ * be used by implementations to validate objects.
131
+ */
132
+ export const GraffitiObjectJSONSchema = {
133
+ type: "object",
134
+ properties: {
135
+ value: { type: "object" },
136
+ channels: { type: "array", items: { type: "string" } },
137
+ allowed: { type: "array", items: { type: "string" }, nullable: true },
138
+ actor: { type: "string" },
139
+ name: { type: "string" },
140
+ source: { type: "string" },
141
+ lastModified: { type: "number" },
142
+ tombstone: { type: "boolean" },
143
+ },
144
+ required: [
145
+ "value",
146
+ "channels",
147
+ "actor",
148
+ "name",
149
+ "source",
150
+ "lastModified",
151
+ "tombstone",
152
+ ],
153
+ } as const satisfies JSONSchema;
125
154
 
126
155
  /**
127
156
  * This is a subset of properties from {@link GraffitiObjectBase} that uniquely
@@ -156,12 +185,22 @@ export type GraffitiLocation = Pick<
156
185
  * This object does not need a {@link GraffitiObjectBase.lastModified | `lastModified`} or {@link GraffitiObjectBase.tombstone | `tombstone`}
157
186
  * property since these are automatically generated by the Graffiti system.
158
187
  */
159
- export type GraffitiPutObject<Schema> = Pick<
188
+ export type GraffitiPutObject<Schema extends JSONSchema> = Pick<
160
189
  GraffitiObjectBase,
161
190
  "value" | "channels" | "allowed"
162
191
  > &
163
- Partial<GraffitiLocation> &
164
- JTDDataType<Schema>;
192
+ Partial<GraffitiObjectBase> &
193
+ FromSchema<Schema & typeof GraffitiPutObjectJSONSchema>;
194
+
195
+ /**
196
+ * A JSON Schema equivalent to the {@link GraffitiPutObject} type.
197
+ * Needed internally for type inference of JSON Schemas, but can
198
+ * be used by implementations to validate objects.
199
+ */
200
+ export const GraffitiPutObjectJSONSchema = {
201
+ ...GraffitiObjectJSONSchema,
202
+ required: ["value", "channels"],
203
+ } as const satisfies JSONSchema;
165
204
 
166
205
  /**
167
206
  * This object contains information that