@graffiti-garden/api 0.2.9 → 0.2.11
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/tests/synchronize.d.ts.map +1 -1
- package/dist/tests.mjs +50 -11
- package/dist/tests.mjs.map +3 -3
- package/package.json +1 -1
- package/tests/channel-stats.ts +2 -2
- package/tests/crud.ts +2 -2
- package/tests/discover.ts +2 -2
- package/tests/orphans.ts +2 -2
- package/tests/synchronize.ts +52 -3
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"synchronize.d.ts","sourceRoot":"","sources":["../../tests/synchronize.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAG7E,eAAO,MAAM,wBAAwB,gBACtB,eAAe,eACf,MAAM,eAAe,GAAG,OAAO,CAAC,eAAe,CAAC,eAChD,MAAM,eAAe,GAAG,OAAO,CAAC,eAAe,CAAC,
|
|
1
|
+
{"version":3,"file":"synchronize.d.ts","sourceRoot":"","sources":["../../tests/synchronize.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAG7E,eAAO,MAAM,wBAAwB,gBACtB,eAAe,eACf,MAAM,eAAe,GAAG,OAAO,CAAC,eAAe,CAAC,eAChD,MAAM,eAAe,GAAG,OAAO,CAAC,eAAe,CAAC,SA2Y9D,CAAC"}
|
package/dist/tests.mjs
CHANGED
|
@@ -63,7 +63,7 @@ var graffitiLocationTests = (useGraffiti) => {
|
|
|
63
63
|
};
|
|
64
64
|
|
|
65
65
|
// tests/crud.ts
|
|
66
|
-
import { it as it2, expect as expect2, describe as describe2,
|
|
66
|
+
import { it as it2, expect as expect2, describe as describe2, beforeAll } from "vitest";
|
|
67
67
|
import {
|
|
68
68
|
GraffitiErrorNotFound,
|
|
69
69
|
GraffitiErrorSchemaMismatch,
|
|
@@ -83,7 +83,7 @@ var graffitiCRUDTests = (useGraffiti, useSession1, useSession2) => {
|
|
|
83
83
|
let session;
|
|
84
84
|
let session1;
|
|
85
85
|
let session2;
|
|
86
|
-
|
|
86
|
+
beforeAll(async () => {
|
|
87
87
|
graffiti = useGraffiti();
|
|
88
88
|
session1 = await useSession1();
|
|
89
89
|
session = session1;
|
|
@@ -471,14 +471,14 @@ var graffitiCRUDTests = (useGraffiti, useSession1, useSession2) => {
|
|
|
471
471
|
};
|
|
472
472
|
|
|
473
473
|
// tests/synchronize.ts
|
|
474
|
-
import { it as it3, expect as expect3, describe as describe3, assert as assert2,
|
|
474
|
+
import { it as it3, expect as expect3, describe as describe3, assert as assert2, beforeAll as beforeAll2 } from "vitest";
|
|
475
475
|
var graffitiSynchronizeTests = (useGraffiti, useSession1, useSession2) => {
|
|
476
476
|
describe3.concurrent("synchronizeDiscover", () => {
|
|
477
477
|
let graffiti;
|
|
478
478
|
let session;
|
|
479
479
|
let session1;
|
|
480
480
|
let session2;
|
|
481
|
-
|
|
481
|
+
beforeAll2(async () => {
|
|
482
482
|
graffiti = useGraffiti();
|
|
483
483
|
session1 = await useSession1();
|
|
484
484
|
session = session1;
|
|
@@ -636,6 +636,45 @@ var graffitiSynchronizeTests = (useGraffiti, useSession1, useSession2) => {
|
|
|
636
636
|
channels.filter((c) => oldChannels.includes(c))
|
|
637
637
|
);
|
|
638
638
|
});
|
|
639
|
+
it3("synchronize happens before putters", async () => {
|
|
640
|
+
const object = randomPutObject();
|
|
641
|
+
const iterator = graffiti.synchronizeDiscover(object.channels, {});
|
|
642
|
+
for (let i = 0; i < 10; i++) {
|
|
643
|
+
const next = iterator.next();
|
|
644
|
+
const putted = graffiti.put(object, session);
|
|
645
|
+
let first = void 0;
|
|
646
|
+
next.then(() => {
|
|
647
|
+
if (!first) first = "synchronize";
|
|
648
|
+
});
|
|
649
|
+
putted.then(() => {
|
|
650
|
+
if (!first) first = "put";
|
|
651
|
+
});
|
|
652
|
+
await putted;
|
|
653
|
+
expect3(first).toBe("synchronize");
|
|
654
|
+
const patched = graffiti.patch({}, await putted, session);
|
|
655
|
+
const next2 = iterator.next();
|
|
656
|
+
let second = void 0;
|
|
657
|
+
next2.then(() => {
|
|
658
|
+
if (!second) second = "synchronize";
|
|
659
|
+
});
|
|
660
|
+
patched.then(() => {
|
|
661
|
+
if (!second) second = "patch";
|
|
662
|
+
});
|
|
663
|
+
await patched;
|
|
664
|
+
expect3(second).toBe("synchronize");
|
|
665
|
+
const deleted = graffiti.delete(await putted, session);
|
|
666
|
+
const next3 = iterator.next();
|
|
667
|
+
let third = void 0;
|
|
668
|
+
next3.then(() => {
|
|
669
|
+
if (!third) third = "synchronize";
|
|
670
|
+
});
|
|
671
|
+
deleted.then(() => {
|
|
672
|
+
if (!third) third = "delete";
|
|
673
|
+
});
|
|
674
|
+
await deleted;
|
|
675
|
+
expect3(third).toBe("synchronize");
|
|
676
|
+
}
|
|
677
|
+
});
|
|
639
678
|
it3("not allowed", async () => {
|
|
640
679
|
const allChannels = [randomString(), randomString(), randomString()];
|
|
641
680
|
const channels = allChannels.slice(1);
|
|
@@ -673,7 +712,7 @@ var graffitiSynchronizeTests = (useGraffiti, useSession1, useSession2) => {
|
|
|
673
712
|
let session;
|
|
674
713
|
let session1;
|
|
675
714
|
let session2;
|
|
676
|
-
|
|
715
|
+
beforeAll2(async () => {
|
|
677
716
|
graffiti = useGraffiti();
|
|
678
717
|
session1 = await useSession1();
|
|
679
718
|
session = session1;
|
|
@@ -749,14 +788,14 @@ var graffitiSynchronizeTests = (useGraffiti, useSession1, useSession2) => {
|
|
|
749
788
|
};
|
|
750
789
|
|
|
751
790
|
// tests/discover.ts
|
|
752
|
-
import { it as it4, expect as expect4, describe as describe4, assert as assert3,
|
|
791
|
+
import { it as it4, expect as expect4, describe as describe4, assert as assert3, beforeAll as beforeAll3 } from "vitest";
|
|
753
792
|
var graffitiDiscoverTests = (useGraffiti, useSession1, useSession2) => {
|
|
754
793
|
describe4.concurrent("discover", { timeout: 2e4 }, () => {
|
|
755
794
|
let graffiti;
|
|
756
795
|
let session;
|
|
757
796
|
let session1;
|
|
758
797
|
let session2;
|
|
759
|
-
|
|
798
|
+
beforeAll3(async () => {
|
|
760
799
|
graffiti = useGraffiti();
|
|
761
800
|
session1 = await useSession1();
|
|
762
801
|
session = session1;
|
|
@@ -1249,14 +1288,14 @@ var graffitiDiscoverTests = (useGraffiti, useSession1, useSession2) => {
|
|
|
1249
1288
|
};
|
|
1250
1289
|
|
|
1251
1290
|
// tests/orphans.ts
|
|
1252
|
-
import { it as it5, expect as expect5, describe as describe5,
|
|
1291
|
+
import { it as it5, expect as expect5, describe as describe5, beforeAll as beforeAll4 } from "vitest";
|
|
1253
1292
|
var graffitiOrphanTests = (useGraffiti, useSession1, useSession2) => {
|
|
1254
1293
|
describe5("recoverOrphans", { timeout: 2e4 }, () => {
|
|
1255
1294
|
let graffiti;
|
|
1256
1295
|
let session;
|
|
1257
1296
|
let session1;
|
|
1258
1297
|
let session2;
|
|
1259
|
-
|
|
1298
|
+
beforeAll4(async () => {
|
|
1260
1299
|
graffiti = useGraffiti();
|
|
1261
1300
|
session1 = await useSession1();
|
|
1262
1301
|
session = session1;
|
|
@@ -1316,14 +1355,14 @@ var graffitiOrphanTests = (useGraffiti, useSession1, useSession2) => {
|
|
|
1316
1355
|
};
|
|
1317
1356
|
|
|
1318
1357
|
// tests/channel-stats.ts
|
|
1319
|
-
import { it as it6, expect as expect6, describe as describe6, assert as assert5,
|
|
1358
|
+
import { it as it6, expect as expect6, describe as describe6, assert as assert5, beforeAll as beforeAll5 } from "vitest";
|
|
1320
1359
|
var graffitiChannelStatsTests = (useGraffiti, useSession1, useSession2) => {
|
|
1321
1360
|
describe6("channel stats", { timeout: 2e4 }, () => {
|
|
1322
1361
|
let graffiti;
|
|
1323
1362
|
let session;
|
|
1324
1363
|
let session1;
|
|
1325
1364
|
let session2;
|
|
1326
|
-
|
|
1365
|
+
beforeAll5(async () => {
|
|
1327
1366
|
graffiti = useGraffiti();
|
|
1328
1367
|
session1 = await useSession1();
|
|
1329
1368
|
session = session1;
|
package/dist/tests.mjs.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../tests/location.ts", "../tests/utils.ts", "../tests/crud.ts", "../tests/synchronize.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, beforeEach } 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 beforeEach(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, beforeEach } from \"vitest\";\nimport type { GraffitiFactory, GraffitiSession } from \"@graffiti-garden/api\";\nimport { randomPutObject, randomString } from \"./utils\";\n\nexport const graffitiSynchronizeTests = (\n useGraffiti: GraffitiFactory,\n useSession1: () => GraffitiSession | Promise<GraffitiSession>,\n useSession2: () => GraffitiSession | Promise<GraffitiSession>,\n) => {\n describe.concurrent(\"synchronizeDiscover\", () => {\n let graffiti: ReturnType<typeof useGraffiti>;\n let session: GraffitiSession;\n let session1: GraffitiSession;\n let session2: GraffitiSession;\n beforeEach(async () => {\n graffiti = useGraffiti();\n session1 = await useSession1();\n session = session1;\n session2 = await useSession2();\n });\n\n it(\"get\", async () => {\n const graffiti1 = useGraffiti();\n\n const object = randomPutObject();\n const channels = object.channels.slice(1);\n const putted = await graffiti1.put(object, session);\n\n const graffiti2 = useGraffiti();\n const next = graffiti2.synchronizeDiscover(channels, {}).next();\n const gotten = await graffiti2.get(putted, {}, session);\n\n const result = (await next).value;\n if (!result || result.error) {\n throw new Error(\"Error in synchronize\");\n }\n expect(result.value.value).toEqual(object.value);\n expect(result.value.channels).toEqual(channels);\n expect(result.value.tombstone).toBe(false);\n expect(result.value.lastModified).toEqual(gotten.lastModified);\n });\n\n it(\"put\", async () => {\n const beforeChannel = randomString();\n const afterChannel = randomString();\n const sharedChannel = randomString();\n\n const oldValue = { hello: \"world\" };\n const oldChannels = [beforeChannel, sharedChannel];\n const putted = await graffiti.put(\n {\n value: oldValue,\n channels: oldChannels,\n },\n session,\n );\n\n // Start listening for changes...\n const before = graffiti.synchronizeDiscover([beforeChannel], {}).next();\n const after = graffiti.synchronizeDiscover([afterChannel], {}).next();\n const shared = graffiti.synchronizeDiscover([sharedChannel], {}).next();\n\n // Replace the object\n const newValue = { goodbye: \"world\" };\n const newChannels = [afterChannel, sharedChannel];\n await graffiti.put(\n {\n ...putted,\n value: newValue,\n channels: newChannels,\n },\n session,\n );\n\n const beforeResult = (await before).value;\n const afterResult = (await after).value;\n const sharedResult = (await shared).value;\n if (\n !beforeResult ||\n beforeResult.error ||\n !afterResult ||\n afterResult.error ||\n !sharedResult ||\n sharedResult.error\n ) {\n throw new Error(\"Error in synchronize\");\n }\n\n expect(beforeResult.value.value).toEqual(oldValue);\n expect(beforeResult.value.channels).toEqual([beforeChannel]);\n expect(beforeResult.value.tombstone).toBe(true);\n expect(afterResult.value.value).toEqual(newValue);\n expect(afterResult.value.channels).toEqual([afterChannel]);\n expect(afterResult.value.tombstone).toBe(false);\n expect(sharedResult.value.value).toEqual(newValue);\n expect(sharedResult.value.channels).toEqual([sharedChannel]);\n expect(sharedResult.value.tombstone).toBe(false);\n expect(beforeResult.value.lastModified).toEqual(\n afterResult.value.lastModified,\n );\n expect(sharedResult.value.lastModified).toEqual(\n afterResult.value.lastModified,\n );\n });\n\n it(\"patch\", async () => {\n const beforeChannel = randomString();\n const afterChannel = randomString();\n const sharedChannel = randomString();\n\n const oldValue = { hello: \"world\" };\n const oldChannels = [beforeChannel, sharedChannel];\n const putted = await graffiti.put(\n {\n value: oldValue,\n channels: oldChannels,\n },\n session,\n );\n\n // Start listening for changes...\n const before = graffiti.synchronizeDiscover([beforeChannel], {}).next();\n const after = graffiti.synchronizeDiscover([afterChannel], {}).next();\n const shared = graffiti.synchronizeDiscover([sharedChannel], {}).next();\n\n await graffiti.patch(\n {\n value: [\n {\n op: \"add\",\n path: \"/something\",\n value: \"new value\",\n },\n ],\n channels: [\n {\n op: \"add\",\n path: \"/-\",\n value: afterChannel,\n },\n {\n op: \"remove\",\n path: `/${oldChannels.indexOf(beforeChannel)}`,\n },\n ],\n },\n putted,\n session,\n );\n\n const beforeResult = (await before).value;\n const afterResult = (await after).value;\n const sharedResult = (await shared).value;\n if (\n !beforeResult ||\n beforeResult.error ||\n !afterResult ||\n afterResult.error ||\n !sharedResult ||\n sharedResult.error\n ) {\n throw new Error(\"Error in synchronize\");\n }\n\n const newValue = { ...oldValue, something: \"new value\" };\n const newChannels = [sharedChannel, afterChannel];\n expect(beforeResult.value.value).toEqual(oldValue);\n expect(beforeResult.value.channels).toEqual([beforeChannel]);\n expect(beforeResult.value.tombstone).toBe(true);\n expect(afterResult.value.value).toEqual(newValue);\n expect(afterResult.value.channels).toEqual([afterChannel]);\n expect(afterResult.value.tombstone).toBe(false);\n expect(sharedResult.value.value).toEqual(newValue);\n expect(sharedResult.value.channels).toEqual([sharedChannel]);\n expect(sharedResult.value.tombstone).toBe(false);\n expect(beforeResult.value.lastModified).toEqual(\n afterResult.value.lastModified,\n );\n expect(sharedResult.value.lastModified).toEqual(\n afterResult.value.lastModified,\n );\n });\n\n it(\"delete\", async () => {\n const channels = [randomString(), randomString(), randomString()];\n\n const oldValue = { hello: \"world\" };\n const oldChannels = [randomString(), ...channels.slice(1)];\n const putted = await graffiti.put(\n {\n value: oldValue,\n channels: oldChannels,\n },\n session,\n );\n\n const next = graffiti.synchronizeDiscover(channels, {}).next();\n\n graffiti.delete(putted, session);\n\n const result = (await next).value;\n if (!result || result.error) {\n throw new Error(\"Error in synchronize\");\n }\n expect(result.value.tombstone).toBe(true);\n expect(result.value.value).toEqual(oldValue);\n expect(result.value.channels).toEqual(\n channels.filter((c) => oldChannels.includes(c)),\n );\n });\n\n it(\"not allowed\", async () => {\n const allChannels = [randomString(), randomString(), randomString()];\n const channels = allChannels.slice(1);\n\n const creatorNext = graffiti\n .synchronizeDiscover(channels, {}, session1)\n .next();\n const allowedNext = graffiti\n .synchronizeDiscover(channels, {}, session2)\n .next();\n const noSession = graffiti.synchronizeDiscover(channels, {}).next();\n\n const value = {\n hello: \"world\",\n };\n const allowed = [randomString(), session2.actor];\n await graffiti.put({ value, channels: allChannels, allowed }, session1);\n\n // Expect no session to time out!\n await expect(\n Promise.race([\n noSession,\n new Promise((resolve, rejects) =>\n setTimeout(rejects, 100, \"Timeout\"),\n ),\n ]),\n ).rejects.toThrow(\"Timeout\");\n\n const creatorResult = (await creatorNext).value;\n const allowedResult = (await allowedNext).value;\n\n if (\n !creatorResult ||\n creatorResult.error ||\n !allowedResult ||\n allowedResult.error\n ) {\n throw new Error(\"Error in synchronize\");\n }\n\n expect(creatorResult.value.value).toEqual(value);\n expect(creatorResult.value.allowed).toEqual(allowed);\n expect(creatorResult.value.channels).toEqual(allChannels);\n expect(allowedResult.value.value).toEqual(value);\n expect(allowedResult.value.allowed).toEqual([session2.actor]);\n expect(allowedResult.value.channels).toEqual(channels);\n });\n });\n\n describe.concurrent(\"synchronizeGet\", () => {\n let graffiti: ReturnType<typeof useGraffiti>;\n let session: GraffitiSession;\n let session1: GraffitiSession;\n let session2: GraffitiSession;\n beforeEach(async () => {\n graffiti = useGraffiti();\n session1 = await useSession1();\n session = session1;\n session2 = await useSession2();\n });\n\n it(\"replace, delete\", async () => {\n const object = randomPutObject();\n const putted = await graffiti.put(object, session);\n\n const iterator = graffiti.synchronizeGet(putted, {});\n const next = iterator.next();\n\n // Change the object\n const newValue = { goodbye: \"world\" };\n const putted2 = await graffiti.put(\n {\n ...putted,\n value: newValue,\n },\n session,\n );\n\n const result = (await next).value;\n assert(result && !result.error);\n\n expect(result.value.value).toEqual(newValue);\n expect(result.value.actor).toEqual(session.actor);\n expect(result.value.channels).toEqual([]);\n expect(result.value.tombstone).toBe(false);\n expect(result.value.lastModified).toEqual(putted2.lastModified);\n expect(result.value.allowed).toBeUndefined();\n\n // Delete the object\n const deleted = await graffiti.delete(putted2, session);\n const result2 = (await iterator.next()).value;\n assert(result2 && !result2.error);\n expect(result2.value.tombstone).toBe(true);\n expect(result2.value.lastModified).toEqual(deleted.lastModified);\n\n // Put something else\n await graffiti.put(randomPutObject(), session);\n await expect(\n Promise.race([\n iterator.next(),\n new Promise((resolve, reject) => setTimeout(reject, 100, \"Timeout\")),\n ]),\n ).rejects.toThrow(\"Timeout\");\n });\n\n it(\"not allowed\", async () => {\n const object = randomPutObject();\n const putted = await graffiti.put(object, session1);\n\n const iterator1 = graffiti.synchronizeGet(putted, {}, session1);\n const iterator2 = graffiti.synchronizeGet(putted, {}, session2);\n\n const next1 = iterator1.next();\n const next2 = iterator2.next();\n\n const newValue = { goodbye: \"world\" };\n const putted2 = await graffiti.put(\n {\n ...putted,\n ...object,\n allowed: [],\n value: newValue,\n },\n session1,\n );\n const result1 = (await next1).value;\n const result2 = (await next2).value;\n assert(result1 && !result1.error);\n assert(result2 && !result2.error);\n\n expect(result1.value.value).toEqual(newValue);\n expect(result2.value.value).toEqual(object.value);\n expect(result1.value.actor).toEqual(session1.actor);\n expect(result2.value.actor).toEqual(session1.actor);\n expect(result1.value.channels).toEqual(object.channels);\n expect(result2.value.channels).toEqual([]);\n expect(result1.value.tombstone).toBe(false);\n expect(result2.value.tombstone).toBe(true);\n expect(result1.value.lastModified).toEqual(putted2.lastModified);\n expect(result2.value.lastModified).toEqual(putted2.lastModified);\n });\n });\n};\n", "import { it, expect, describe, assert, beforeEach } 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 beforeEach(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, beforeEach } 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 beforeEach(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, beforeEach } 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 beforeEach(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
|
-
"names": ["it", "expect", "describe", "describe", "it", "expect", "it", "expect", "describe", "assert", "
|
|
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 { GraffitiFactory, GraffitiSession } from \"@graffiti-garden/api\";\nimport { randomPutObject, randomString } from \"./utils\";\n\nexport const graffitiSynchronizeTests = (\n useGraffiti: GraffitiFactory,\n useSession1: () => GraffitiSession | Promise<GraffitiSession>,\n useSession2: () => GraffitiSession | Promise<GraffitiSession>,\n) => {\n describe.concurrent(\"synchronizeDiscover\", () => {\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(\"get\", async () => {\n const graffiti1 = useGraffiti();\n\n const object = randomPutObject();\n const channels = object.channels.slice(1);\n const putted = await graffiti1.put(object, session);\n\n const graffiti2 = useGraffiti();\n const next = graffiti2.synchronizeDiscover(channels, {}).next();\n const gotten = await graffiti2.get(putted, {}, session);\n\n const result = (await next).value;\n if (!result || result.error) {\n throw new Error(\"Error in synchronize\");\n }\n expect(result.value.value).toEqual(object.value);\n expect(result.value.channels).toEqual(channels);\n expect(result.value.tombstone).toBe(false);\n expect(result.value.lastModified).toEqual(gotten.lastModified);\n });\n\n it(\"put\", async () => {\n const beforeChannel = randomString();\n const afterChannel = randomString();\n const sharedChannel = randomString();\n\n const oldValue = { hello: \"world\" };\n const oldChannels = [beforeChannel, sharedChannel];\n const putted = await graffiti.put(\n {\n value: oldValue,\n channels: oldChannels,\n },\n session,\n );\n\n // Start listening for changes...\n const before = graffiti.synchronizeDiscover([beforeChannel], {}).next();\n const after = graffiti.synchronizeDiscover([afterChannel], {}).next();\n const shared = graffiti.synchronizeDiscover([sharedChannel], {}).next();\n\n // Replace the object\n const newValue = { goodbye: \"world\" };\n const newChannels = [afterChannel, sharedChannel];\n await graffiti.put(\n {\n ...putted,\n value: newValue,\n channels: newChannels,\n },\n session,\n );\n\n const beforeResult = (await before).value;\n const afterResult = (await after).value;\n const sharedResult = (await shared).value;\n if (\n !beforeResult ||\n beforeResult.error ||\n !afterResult ||\n afterResult.error ||\n !sharedResult ||\n sharedResult.error\n ) {\n throw new Error(\"Error in synchronize\");\n }\n\n expect(beforeResult.value.value).toEqual(oldValue);\n expect(beforeResult.value.channels).toEqual([beforeChannel]);\n expect(beforeResult.value.tombstone).toBe(true);\n expect(afterResult.value.value).toEqual(newValue);\n expect(afterResult.value.channels).toEqual([afterChannel]);\n expect(afterResult.value.tombstone).toBe(false);\n expect(sharedResult.value.value).toEqual(newValue);\n expect(sharedResult.value.channels).toEqual([sharedChannel]);\n expect(sharedResult.value.tombstone).toBe(false);\n expect(beforeResult.value.lastModified).toEqual(\n afterResult.value.lastModified,\n );\n expect(sharedResult.value.lastModified).toEqual(\n afterResult.value.lastModified,\n );\n });\n\n it(\"patch\", async () => {\n const beforeChannel = randomString();\n const afterChannel = randomString();\n const sharedChannel = randomString();\n\n const oldValue = { hello: \"world\" };\n const oldChannels = [beforeChannel, sharedChannel];\n const putted = await graffiti.put(\n {\n value: oldValue,\n channels: oldChannels,\n },\n session,\n );\n\n // Start listening for changes...\n const before = graffiti.synchronizeDiscover([beforeChannel], {}).next();\n const after = graffiti.synchronizeDiscover([afterChannel], {}).next();\n const shared = graffiti.synchronizeDiscover([sharedChannel], {}).next();\n\n await graffiti.patch(\n {\n value: [\n {\n op: \"add\",\n path: \"/something\",\n value: \"new value\",\n },\n ],\n channels: [\n {\n op: \"add\",\n path: \"/-\",\n value: afterChannel,\n },\n {\n op: \"remove\",\n path: `/${oldChannels.indexOf(beforeChannel)}`,\n },\n ],\n },\n putted,\n session,\n );\n\n const beforeResult = (await before).value;\n const afterResult = (await after).value;\n const sharedResult = (await shared).value;\n if (\n !beforeResult ||\n beforeResult.error ||\n !afterResult ||\n afterResult.error ||\n !sharedResult ||\n sharedResult.error\n ) {\n throw new Error(\"Error in synchronize\");\n }\n\n const newValue = { ...oldValue, something: \"new value\" };\n const newChannels = [sharedChannel, afterChannel];\n expect(beforeResult.value.value).toEqual(oldValue);\n expect(beforeResult.value.channels).toEqual([beforeChannel]);\n expect(beforeResult.value.tombstone).toBe(true);\n expect(afterResult.value.value).toEqual(newValue);\n expect(afterResult.value.channels).toEqual([afterChannel]);\n expect(afterResult.value.tombstone).toBe(false);\n expect(sharedResult.value.value).toEqual(newValue);\n expect(sharedResult.value.channels).toEqual([sharedChannel]);\n expect(sharedResult.value.tombstone).toBe(false);\n expect(beforeResult.value.lastModified).toEqual(\n afterResult.value.lastModified,\n );\n expect(sharedResult.value.lastModified).toEqual(\n afterResult.value.lastModified,\n );\n });\n\n it(\"delete\", async () => {\n const channels = [randomString(), randomString(), randomString()];\n\n const oldValue = { hello: \"world\" };\n const oldChannels = [randomString(), ...channels.slice(1)];\n const putted = await graffiti.put(\n {\n value: oldValue,\n channels: oldChannels,\n },\n session,\n );\n\n const next = graffiti.synchronizeDiscover(channels, {}).next();\n\n graffiti.delete(putted, session);\n\n const result = (await next).value;\n if (!result || result.error) {\n throw new Error(\"Error in synchronize\");\n }\n expect(result.value.tombstone).toBe(true);\n expect(result.value.value).toEqual(oldValue);\n expect(result.value.channels).toEqual(\n channels.filter((c) => oldChannels.includes(c)),\n );\n });\n\n it(\"synchronize happens before putters\", async () => {\n const object = randomPutObject();\n const iterator = graffiti.synchronizeDiscover(object.channels, {});\n\n for (let i = 0; i < 10; i++) {\n const next = iterator.next();\n const putted = graffiti.put(object, session);\n\n let first: undefined | string = undefined;\n next.then(() => {\n if (!first) first = \"synchronize\";\n });\n putted.then(() => {\n if (!first) first = \"put\";\n });\n await putted;\n\n expect(first).toBe(\"synchronize\");\n\n const patched = graffiti.patch({}, await putted, session);\n const next2 = iterator.next();\n\n let second: undefined | string = undefined;\n next2.then(() => {\n if (!second) second = \"synchronize\";\n });\n patched.then(() => {\n if (!second) second = \"patch\";\n });\n await patched;\n\n expect(second).toBe(\"synchronize\");\n\n const deleted = graffiti.delete(await putted, session);\n const next3 = iterator.next();\n\n let third: undefined | string = undefined;\n next3.then(() => {\n if (!third) third = \"synchronize\";\n });\n deleted.then(() => {\n if (!third) third = \"delete\";\n });\n await deleted;\n\n expect(third).toBe(\"synchronize\");\n }\n });\n\n it(\"not allowed\", async () => {\n const allChannels = [randomString(), randomString(), randomString()];\n const channels = allChannels.slice(1);\n\n const creatorNext = graffiti\n .synchronizeDiscover(channels, {}, session1)\n .next();\n const allowedNext = graffiti\n .synchronizeDiscover(channels, {}, session2)\n .next();\n const noSession = graffiti.synchronizeDiscover(channels, {}).next();\n\n const value = {\n hello: \"world\",\n };\n const allowed = [randomString(), session2.actor];\n await graffiti.put({ value, channels: allChannels, allowed }, session1);\n\n // Expect no session to time out!\n await expect(\n Promise.race([\n noSession,\n new Promise((resolve, rejects) =>\n setTimeout(rejects, 100, \"Timeout\"),\n ),\n ]),\n ).rejects.toThrow(\"Timeout\");\n\n const creatorResult = (await creatorNext).value;\n const allowedResult = (await allowedNext).value;\n\n if (\n !creatorResult ||\n creatorResult.error ||\n !allowedResult ||\n allowedResult.error\n ) {\n throw new Error(\"Error in synchronize\");\n }\n\n expect(creatorResult.value.value).toEqual(value);\n expect(creatorResult.value.allowed).toEqual(allowed);\n expect(creatorResult.value.channels).toEqual(allChannels);\n expect(allowedResult.value.value).toEqual(value);\n expect(allowedResult.value.allowed).toEqual([session2.actor]);\n expect(allowedResult.value.channels).toEqual(channels);\n });\n });\n\n describe.concurrent(\"synchronizeGet\", () => {\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(\"replace, delete\", async () => {\n const object = randomPutObject();\n const putted = await graffiti.put(object, session);\n\n const iterator = graffiti.synchronizeGet(putted, {});\n const next = iterator.next();\n\n // Change the object\n const newValue = { goodbye: \"world\" };\n const putted2 = await graffiti.put(\n {\n ...putted,\n value: newValue,\n },\n session,\n );\n\n const result = (await next).value;\n assert(result && !result.error);\n\n expect(result.value.value).toEqual(newValue);\n expect(result.value.actor).toEqual(session.actor);\n expect(result.value.channels).toEqual([]);\n expect(result.value.tombstone).toBe(false);\n expect(result.value.lastModified).toEqual(putted2.lastModified);\n expect(result.value.allowed).toBeUndefined();\n\n // Delete the object\n const deleted = await graffiti.delete(putted2, session);\n const result2 = (await iterator.next()).value;\n assert(result2 && !result2.error);\n expect(result2.value.tombstone).toBe(true);\n expect(result2.value.lastModified).toEqual(deleted.lastModified);\n\n // Put something else\n await graffiti.put(randomPutObject(), session);\n await expect(\n Promise.race([\n iterator.next(),\n new Promise((resolve, reject) => setTimeout(reject, 100, \"Timeout\")),\n ]),\n ).rejects.toThrow(\"Timeout\");\n });\n\n it(\"not allowed\", async () => {\n const object = randomPutObject();\n const putted = await graffiti.put(object, session1);\n\n const iterator1 = graffiti.synchronizeGet(putted, {}, session1);\n const iterator2 = graffiti.synchronizeGet(putted, {}, session2);\n\n const next1 = iterator1.next();\n const next2 = iterator2.next();\n\n const newValue = { goodbye: \"world\" };\n const putted2 = await graffiti.put(\n {\n ...putted,\n ...object,\n allowed: [],\n value: newValue,\n },\n session1,\n );\n const result1 = (await next1).value;\n const result2 = (await next2).value;\n assert(result1 && !result1.error);\n assert(result2 && !result2.error);\n\n expect(result1.value.value).toEqual(newValue);\n expect(result2.value.value).toEqual(object.value);\n expect(result1.value.actor).toEqual(session1.actor);\n expect(result2.value.actor).toEqual(session1.actor);\n expect(result1.value.channels).toEqual(object.channels);\n expect(result2.value.channels).toEqual([]);\n expect(result1.value.tombstone).toBe(false);\n expect(result2.value.tombstone).toBe(true);\n expect(result1.value.lastModified).toEqual(putted2.lastModified);\n expect(result2.value.lastModified).toEqual(putted2.lastModified);\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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",
|
|
6
|
+
"names": ["it", "expect", "describe", "describe", "it", "expect", "it", "expect", "describe", "assert", "beforeAll", "describe", "beforeAll", "it", "expect", "assert", "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
package/tests/channel-stats.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { it, expect, describe, assert,
|
|
1
|
+
import { it, expect, describe, assert, beforeAll } from "vitest";
|
|
2
2
|
import type { Graffiti, GraffitiSession } from "@graffiti-garden/api";
|
|
3
3
|
import { randomString } from "./utils";
|
|
4
4
|
|
|
@@ -15,7 +15,7 @@ export const graffitiChannelStatsTests = (
|
|
|
15
15
|
let session: GraffitiSession;
|
|
16
16
|
let session1: GraffitiSession;
|
|
17
17
|
let session2: GraffitiSession;
|
|
18
|
-
|
|
18
|
+
beforeAll(async () => {
|
|
19
19
|
graffiti = useGraffiti();
|
|
20
20
|
session1 = await useSession1();
|
|
21
21
|
session = session1;
|
package/tests/crud.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { it, expect, describe,
|
|
1
|
+
import { it, expect, describe, beforeAll } from "vitest";
|
|
2
2
|
import type {
|
|
3
3
|
Graffiti,
|
|
4
4
|
GraffitiSession,
|
|
@@ -29,7 +29,7 @@ export const graffitiCRUDTests = (
|
|
|
29
29
|
let session: GraffitiSession;
|
|
30
30
|
let session1: GraffitiSession;
|
|
31
31
|
let session2: GraffitiSession;
|
|
32
|
-
|
|
32
|
+
beforeAll(async () => {
|
|
33
33
|
graffiti = useGraffiti();
|
|
34
34
|
session1 = await useSession1();
|
|
35
35
|
session = session1;
|
package/tests/discover.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { it, expect, describe, assert,
|
|
1
|
+
import { it, expect, describe, assert, beforeAll } from "vitest";
|
|
2
2
|
import type {
|
|
3
3
|
Graffiti,
|
|
4
4
|
GraffitiSession,
|
|
@@ -16,7 +16,7 @@ export const graffitiDiscoverTests = (
|
|
|
16
16
|
let session: GraffitiSession;
|
|
17
17
|
let session1: GraffitiSession;
|
|
18
18
|
let session2: GraffitiSession;
|
|
19
|
-
|
|
19
|
+
beforeAll(async () => {
|
|
20
20
|
graffiti = useGraffiti();
|
|
21
21
|
session1 = await useSession1();
|
|
22
22
|
session = session1;
|
package/tests/orphans.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { it, expect, describe, assert,
|
|
1
|
+
import { it, expect, describe, assert, beforeAll } from "vitest";
|
|
2
2
|
import type { Graffiti, GraffitiSession } from "@graffiti-garden/api";
|
|
3
3
|
import { randomPutObject, randomString } from "./utils";
|
|
4
4
|
|
|
@@ -15,7 +15,7 @@ export const graffitiOrphanTests = (
|
|
|
15
15
|
let session: GraffitiSession;
|
|
16
16
|
let session1: GraffitiSession;
|
|
17
17
|
let session2: GraffitiSession;
|
|
18
|
-
|
|
18
|
+
beforeAll(async () => {
|
|
19
19
|
graffiti = useGraffiti();
|
|
20
20
|
session1 = await useSession1();
|
|
21
21
|
session = session1;
|
package/tests/synchronize.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { it, expect, describe, assert,
|
|
1
|
+
import { it, expect, describe, assert, beforeAll } from "vitest";
|
|
2
2
|
import type { GraffitiFactory, GraffitiSession } from "@graffiti-garden/api";
|
|
3
3
|
import { randomPutObject, randomString } from "./utils";
|
|
4
4
|
|
|
@@ -12,7 +12,7 @@ export const graffitiSynchronizeTests = (
|
|
|
12
12
|
let session: GraffitiSession;
|
|
13
13
|
let session1: GraffitiSession;
|
|
14
14
|
let session2: GraffitiSession;
|
|
15
|
-
|
|
15
|
+
beforeAll(async () => {
|
|
16
16
|
graffiti = useGraffiti();
|
|
17
17
|
session1 = await useSession1();
|
|
18
18
|
session = session1;
|
|
@@ -209,6 +209,55 @@ export const graffitiSynchronizeTests = (
|
|
|
209
209
|
);
|
|
210
210
|
});
|
|
211
211
|
|
|
212
|
+
it("synchronize happens before putters", async () => {
|
|
213
|
+
const object = randomPutObject();
|
|
214
|
+
const iterator = graffiti.synchronizeDiscover(object.channels, {});
|
|
215
|
+
|
|
216
|
+
for (let i = 0; i < 10; i++) {
|
|
217
|
+
const next = iterator.next();
|
|
218
|
+
const putted = graffiti.put(object, session);
|
|
219
|
+
|
|
220
|
+
let first: undefined | string = undefined;
|
|
221
|
+
next.then(() => {
|
|
222
|
+
if (!first) first = "synchronize";
|
|
223
|
+
});
|
|
224
|
+
putted.then(() => {
|
|
225
|
+
if (!first) first = "put";
|
|
226
|
+
});
|
|
227
|
+
await putted;
|
|
228
|
+
|
|
229
|
+
expect(first).toBe("synchronize");
|
|
230
|
+
|
|
231
|
+
const patched = graffiti.patch({}, await putted, session);
|
|
232
|
+
const next2 = iterator.next();
|
|
233
|
+
|
|
234
|
+
let second: undefined | string = undefined;
|
|
235
|
+
next2.then(() => {
|
|
236
|
+
if (!second) second = "synchronize";
|
|
237
|
+
});
|
|
238
|
+
patched.then(() => {
|
|
239
|
+
if (!second) second = "patch";
|
|
240
|
+
});
|
|
241
|
+
await patched;
|
|
242
|
+
|
|
243
|
+
expect(second).toBe("synchronize");
|
|
244
|
+
|
|
245
|
+
const deleted = graffiti.delete(await putted, session);
|
|
246
|
+
const next3 = iterator.next();
|
|
247
|
+
|
|
248
|
+
let third: undefined | string = undefined;
|
|
249
|
+
next3.then(() => {
|
|
250
|
+
if (!third) third = "synchronize";
|
|
251
|
+
});
|
|
252
|
+
deleted.then(() => {
|
|
253
|
+
if (!third) third = "delete";
|
|
254
|
+
});
|
|
255
|
+
await deleted;
|
|
256
|
+
|
|
257
|
+
expect(third).toBe("synchronize");
|
|
258
|
+
}
|
|
259
|
+
});
|
|
260
|
+
|
|
212
261
|
it("not allowed", async () => {
|
|
213
262
|
const allChannels = [randomString(), randomString(), randomString()];
|
|
214
263
|
const channels = allChannels.slice(1);
|
|
@@ -263,7 +312,7 @@ export const graffitiSynchronizeTests = (
|
|
|
263
312
|
let session: GraffitiSession;
|
|
264
313
|
let session1: GraffitiSession;
|
|
265
314
|
let session2: GraffitiSession;
|
|
266
|
-
|
|
315
|
+
beforeAll(async () => {
|
|
267
316
|
graffiti = useGraffiti();
|
|
268
317
|
session1 = await useSession1();
|
|
269
318
|
session = session1;
|