@graffiti-garden/api 0.6.3 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,129 +0,0 @@
1
- import { it, expect, describe, assert, beforeAll } from "vitest";
2
- import type { Graffiti, GraffitiSession } from "@graffiti-garden/api";
3
- import { randomString } from "./utils";
4
-
5
- export const graffitiChannelStatsTests = (
6
- useGraffiti: () => Pick<
7
- Graffiti,
8
- "channelStats" | "put" | "delete" | "patch"
9
- >,
10
- useSession1: () => GraffitiSession | Promise<GraffitiSession>,
11
- useSession2: () => GraffitiSession | Promise<GraffitiSession>,
12
- ) => {
13
- describe("channel stats", { timeout: 20000 }, () => {
14
- let graffiti: ReturnType<typeof useGraffiti>;
15
- let session: GraffitiSession;
16
- let session1: GraffitiSession;
17
- let session2: GraffitiSession;
18
- beforeAll(async () => {
19
- graffiti = useGraffiti();
20
- session1 = await useSession1();
21
- session = session1;
22
- session2 = await useSession2();
23
- });
24
-
25
- it("list channels", async () => {
26
- const existingChannels: Map<string, number> = new Map();
27
- const channelIterator1 = graffiti.channelStats(session);
28
- for await (const channel of channelIterator1) {
29
- if (channel.error) continue;
30
- existingChannels.set(channel.value.channel, channel.value.count);
31
- }
32
-
33
- const channels = [randomString(), randomString(), randomString()];
34
-
35
- // Add one value to channels[0],
36
- // two values to both channels[0] and channels[1],
37
- // three values to all channels
38
- // one value to channels[2]
39
- for (let i = 0; i < 3; i++) {
40
- for (let j = 0; j < i + 1; j++) {
41
- await graffiti.put<{}>(
42
- {
43
- value: {
44
- index: j,
45
- },
46
- channels: channels.slice(0, i + 1),
47
- },
48
- session,
49
- );
50
- }
51
- }
52
- await graffiti.put<{}>(
53
- { value: { index: 3 }, channels: [channels[2]] },
54
- session,
55
- );
56
-
57
- const channelIterator2 = graffiti.channelStats(session);
58
- let newChannels: Map<string, number> = new Map();
59
- for await (const channel of channelIterator2) {
60
- if (channel.error) continue;
61
- newChannels.set(channel.value.channel, channel.value.count);
62
- }
63
- // Filter out existing channels
64
- newChannels = new Map(
65
- Array.from(newChannels).filter(
66
- ([channel, count]) => !existingChannels.has(channel),
67
- ),
68
- );
69
- expect(newChannels.size).toBe(3);
70
- expect(newChannels.get(channels[0])).toBe(6);
71
- expect(newChannels.get(channels[1])).toBe(5);
72
- expect(newChannels.get(channels[2])).toBe(4);
73
- });
74
-
75
- it("list channels with deleted channel", async () => {
76
- const channels = [randomString(), randomString(), randomString()];
77
-
78
- // Add an item with two channels
79
- const before = await graffiti.put<{}>(
80
- {
81
- value: { index: 2 },
82
- channels: channels.slice(1),
83
- },
84
- session,
85
- );
86
-
87
- // Add an item with all channels
88
- const first = await graffiti.put<{}>(
89
- { value: { index: 0 }, channels },
90
- session,
91
- );
92
- // But then delete it
93
- await graffiti.delete(first, session);
94
-
95
- // Create a new object with only one channel
96
- const second = await graffiti.put<{}>(
97
- {
98
- value: { index: 1 },
99
- channels: channels.slice(2),
100
- },
101
- session,
102
- );
103
-
104
- const channelIterator = graffiti.channelStats(session);
105
-
106
- let got1 = 0;
107
- let got2 = 0;
108
- for await (const result of channelIterator) {
109
- if (result.error) continue;
110
- const { channel, count, lastModified } = result.value;
111
- assert(
112
- channel !== channels[0],
113
- "There should not be an object in channel[0]",
114
- );
115
- if (channel === channels[1]) {
116
- expect(count).toBe(1);
117
- expect(lastModified).toBe(before.lastModified);
118
- got1++;
119
- } else if (channel === channels[2]) {
120
- expect(count).toBe(2);
121
- expect(lastModified).toBe(second.lastModified);
122
- got2++;
123
- }
124
- }
125
- expect(got1).toBe(1);
126
- expect(got2).toBe(1);
127
- });
128
- });
129
- };
package/tests/orphans.ts DELETED
@@ -1,128 +0,0 @@
1
- import { it, expect, describe, assert, beforeAll } from "vitest";
2
- import type { Graffiti, GraffitiSession } from "@graffiti-garden/api";
3
- import {
4
- randomPutObject,
5
- randomString,
6
- nextStreamValue,
7
- continueStream,
8
- } from "./utils";
9
-
10
- export const graffitiOrphanTests = (
11
- useGraffiti: () => Pick<
12
- Graffiti,
13
- "recoverOrphans" | "put" | "delete" | "patch" | "continueObjectStream"
14
- >,
15
- useSession1: () => GraffitiSession | Promise<GraffitiSession>,
16
- useSession2: () => GraffitiSession | Promise<GraffitiSession>,
17
- ) => {
18
- describe("recoverOrphans", { timeout: 20000 }, () => {
19
- let graffiti: ReturnType<typeof useGraffiti>;
20
- let session: GraffitiSession;
21
- let session1: GraffitiSession;
22
- let session2: GraffitiSession;
23
- beforeAll(async () => {
24
- graffiti = useGraffiti();
25
- session1 = await useSession1();
26
- session = session1;
27
- session2 = await useSession2();
28
- });
29
-
30
- it("list orphans", async () => {
31
- const existingOrphans: string[] = [];
32
- const orphanIterator1 = graffiti.recoverOrphans({}, session);
33
- for await (const orphan of orphanIterator1) {
34
- if (orphan.error) continue;
35
- existingOrphans.push(orphan.object.url);
36
- }
37
-
38
- const object = randomPutObject();
39
- object.channels = [];
40
- const putted = await graffiti.put<{}>(object, session);
41
- const orphanIterator2 = graffiti.recoverOrphans({}, session);
42
- let numResults = 0;
43
- for await (const orphan of orphanIterator2) {
44
- if (orphan.error) continue;
45
- assert(!orphan.tombstone, "orphan is tombstone");
46
- if (orphan.object.url === putted.url) {
47
- numResults++;
48
- expect(orphan.object.lastModified).toBe(putted.lastModified);
49
- }
50
- }
51
- expect(numResults).toBe(1);
52
- });
53
-
54
- for (const continueType of ["continue", "cursor"] as const) {
55
- describe(`continue orphans with ${continueType}`, () => {
56
- it("replaced orphan, no longer", async () => {
57
- const object = randomPutObject();
58
- object.channels = [];
59
- const putOrphan = await graffiti.put<{}>(object, session);
60
-
61
- // Wait for the put to be processed
62
- await new Promise((resolve) => setTimeout(resolve, 10));
63
-
64
- expect(Object.keys(object.value).length).toBeGreaterThanOrEqual(1);
65
- expect(Object.keys(object.value)[0]).toBeTypeOf("string");
66
- const iterator1 = graffiti.recoverOrphans<{}>(
67
- {
68
- properties: {
69
- value: {
70
- properties: {
71
- [Object.keys(object.value)[0]]: {
72
- type: "string",
73
- },
74
- },
75
- required: [Object.keys(object.value)[0]],
76
- },
77
- },
78
- },
79
- session,
80
- );
81
- const value1 = await nextStreamValue<{}>(iterator1);
82
- expect(value1.value).toEqual(object.value);
83
- const returnValue = await iterator1.next();
84
- assert(returnValue.done, "value2 is not done");
85
-
86
- const putNotOrphan = await graffiti.put<{}>(
87
- {
88
- ...putOrphan,
89
- ...object,
90
- channels: [randomString()],
91
- },
92
- session,
93
- );
94
- expect(putNotOrphan.url).toBe(putOrphan.url);
95
- expect(putNotOrphan.lastModified).toBeGreaterThan(
96
- putOrphan.lastModified,
97
- );
98
-
99
- // The tombstone will not appear to a fresh iterator
100
- const orphanIterator = graffiti.recoverOrphans({}, session);
101
- let numResults = 0;
102
- for await (const orphan of orphanIterator) {
103
- if (orphan.error) continue;
104
- if (orphan.object.url === putOrphan.url) {
105
- numResults++;
106
- }
107
- }
108
- expect(numResults).toBe(0);
109
-
110
- const iterator2 = continueStream<{}>(
111
- graffiti,
112
- returnValue.value,
113
- continueType,
114
- session,
115
- );
116
- const value2 = await iterator2.next();
117
- assert(
118
- !value2.done && !value2.value.error,
119
- "value2 is done or has error",
120
- );
121
- assert(value2.value.tombstone, "value2 is not tombstone");
122
- expect(value2.value.object.url).toBe(putOrphan.url);
123
- await expect(iterator2.next()).resolves.toHaveProperty("done", true);
124
- });
125
- });
126
- }
127
- });
128
- };