@graffiti-garden/implementation-decentralized 0.0.10 → 0.1.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.
Files changed (54) hide show
  1. package/LICENSE +4 -673
  2. package/dist/3-protocol/4-graffiti.d.ts.map +1 -1
  3. package/dist/browser/ajv-X6C4R6QN.js +9 -0
  4. package/dist/browser/ajv-X6C4R6QN.js.map +7 -0
  5. package/dist/browser/{build-DM3HADDZ.js → build-KAK33G4E.js} +1 -1
  6. package/dist/browser/{build-DM3HADDZ.js.map → build-KAK33G4E.js.map} +1 -1
  7. package/dist/browser/{graffiti-KV3G3O72-TAZN6KIP.js → graffiti-KV3G3O72-QD3APAKT.js} +1 -1
  8. package/dist/browser/{graffiti-KV3G3O72-TAZN6KIP.js.map → graffiti-KV3G3O72-QD3APAKT.js.map} +1 -1
  9. package/dist/browser/index.js +10 -10
  10. package/dist/browser/index.js.map +4 -4
  11. package/dist/browser/{rock-salt-LI7DAH66-TZP5ZWGV.js → rock-salt-LI7DAH66-M6W5PPFD.js} +1 -1
  12. package/dist/browser/{rock-salt-LI7DAH66-TZP5ZWGV.js.map → rock-salt-LI7DAH66-M6W5PPFD.js.map} +1 -1
  13. package/dist/browser/{style-BOBMBTYJ-GXWKT5M3.js → style-BOBMBTYJ-2YZTO5FX.js} +1 -1
  14. package/dist/browser/{style-BOBMBTYJ-GXWKT5M3.js.map → style-BOBMBTYJ-2YZTO5FX.js.map} +1 -1
  15. package/dist/cjs/3-protocol/4-graffiti.js +4 -1
  16. package/dist/cjs/3-protocol/4-graffiti.js.map +2 -2
  17. package/dist/cjs/index.js +2 -2
  18. package/dist/cjs/index.js.map +2 -2
  19. package/dist/cjs/index.spec.js +54 -41
  20. package/dist/cjs/index.spec.js.map +2 -2
  21. package/dist/esm/3-protocol/4-graffiti.js +4 -1
  22. package/dist/esm/3-protocol/4-graffiti.js.map +2 -2
  23. package/dist/esm/index.js +1 -1
  24. package/dist/esm/index.js.map +2 -2
  25. package/dist/esm/index.spec.js +59 -42
  26. package/dist/esm/index.spec.js.map +2 -2
  27. package/dist/index.d.ts +1 -1
  28. package/dist/index.d.ts.map +1 -1
  29. package/package.json +15 -10
  30. package/src/3-protocol/4-graffiti.ts +8 -1
  31. package/src/index.spec.ts +66 -48
  32. package/src/index.ts +2 -1
  33. package/dist/1-services/2-dids-tests.d.ts +0 -2
  34. package/dist/1-services/2-dids-tests.d.ts.map +0 -1
  35. package/dist/1-services/3-storage-buckets-tests.d.ts +0 -2
  36. package/dist/1-services/3-storage-buckets-tests.d.ts.map +0 -1
  37. package/dist/1-services/4-inboxes-tests.d.ts +0 -2
  38. package/dist/1-services/4-inboxes-tests.d.ts.map +0 -1
  39. package/dist/2-primitives/1-string-encoding-tests.d.ts +0 -2
  40. package/dist/2-primitives/1-string-encoding-tests.d.ts.map +0 -1
  41. package/dist/2-primitives/2-content-addresses-tests.d.ts +0 -2
  42. package/dist/2-primitives/2-content-addresses-tests.d.ts.map +0 -1
  43. package/dist/2-primitives/3-channel-attestations-tests.d.ts +0 -2
  44. package/dist/2-primitives/3-channel-attestations-tests.d.ts.map +0 -1
  45. package/dist/2-primitives/4-allowed-attestations-tests.d.ts +0 -2
  46. package/dist/2-primitives/4-allowed-attestations-tests.d.ts.map +0 -1
  47. package/dist/3-protocol/2-handles-tests.d.ts +0 -2
  48. package/dist/3-protocol/2-handles-tests.d.ts.map +0 -1
  49. package/dist/3-protocol/3-object-encoding-tests.d.ts +0 -2
  50. package/dist/3-protocol/3-object-encoding-tests.d.ts.map +0 -1
  51. package/dist/browser/ajv-LGNUXWV5.js +0 -9
  52. package/dist/browser/ajv-LGNUXWV5.js.map +0 -7
  53. package/dist/index.spec.d.ts +0 -2
  54. package/dist/index.spec.d.ts.map +0 -1
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@graffiti-garden/implementation-decentralized",
3
- "version": "0.0.10",
3
+ "version": "0.1.0",
4
4
  "description": "A client for a decentralized implementation of the Graffiti API",
5
5
  "types": "./dist/index.d.ts",
6
6
  "module": "./dist/esm/index.js",
@@ -27,35 +27,40 @@
27
27
  "author": "Theia Henderson",
28
28
  "license": "GPL-3.0-or-later",
29
29
  "scripts": {
30
- "test": "NODE_TLS_REJECT_UNAUTHORIZED=0 vitest run",
31
- "test:watch": "NODE_TLS_REJECT_UNAUTHORIZED=0 vitest --watch",
32
- "test:coverage": "NODE_TLS_REJECT_UNAUTHORIZED=0 vitest --coverage",
30
+ "check": "tsc --noEmit && tsc -p tsconfig.test.json",
31
+ "test": "vitest run",
32
+ "test:watch": "vitest --watch",
33
+ "test:coverage": "vitest --coverage",
33
34
  "build:types": "tsc --declaration --emitDeclarationOnly",
34
35
  "build:js": "tsx esbuild.config.mts",
35
36
  "build": "rm -rf dist && npm run build:types && npm run build:js",
36
- "prepublishOnly": "npm update && npm test && npm run build"
37
+ "prepublishOnly": "npm test && npm run build"
37
38
  },
38
39
  "repository": {
39
40
  "type": "git",
40
- "url": "git+https://github.com/graffiti-garden/implementation-decentralized.git"
41
+ "url": "git+https://github.com/graffiti-garden/graffiti.git",
42
+ "directory": "implementations/decentralized/client"
41
43
  },
42
44
  "bugs": {
43
- "url": "https://github.com/graffiti-garden/implementation-decentralized/issues"
45
+ "url": "https://github.com/graffiti-garden/graffiti/issues"
44
46
  },
45
47
  "devDependencies": {
46
48
  "@types/js-cookie": "^3.0.6",
47
49
  "@types/node": "^26.1.1",
48
50
  "@vitest/coverage-v8": "^4.0.18",
51
+ "esbuild": "^0.28.1",
52
+ "miniflare": "4.20260730.0",
49
53
  "tsx": "^4.23.1",
50
54
  "typescript": "^7.0.2",
51
55
  "vitest": "^4.0.18"
52
56
  },
53
57
  "dependencies": {
54
- "@graffiti-garden/api": "^1.2.0",
55
- "@graffiti-garden/modal": "^1.0.4",
58
+ "@graffiti-garden/api": "^1.3.0",
59
+ "@graffiti-garden/modal": "^1.1.0",
60
+ "@graffiti-garden/wrapper-runtime-types": "^0.1.0",
56
61
  "@ipld/dag-cbor": "^10.0.1",
57
62
  "@noble/ed25519": "^3.1.0",
58
- "@noble/hashes": "2.2",
63
+ "@noble/hashes": "2.4",
59
64
  "did-resolver": "^5.0.1",
60
65
  "idb": "^8.0.3",
61
66
  "js-cookie": "^3.0.8",
@@ -710,6 +710,13 @@ export class GraffitiDecentralized implements Graffiti {
710
710
  getMedia: Graffiti["getMedia"] = async (...args) => {
711
711
  const [mediaUrl, accept, session] = args;
712
712
 
713
+ if (
714
+ accept?.maxBytes !== undefined &&
715
+ (!Number.isSafeInteger(accept.maxBytes) || accept.maxBytes < 0)
716
+ ) {
717
+ throw new TypeError("maxBytes must be a nonnegative safe integer");
718
+ }
719
+
713
720
  const object = await this.get<typeof MEDIA_OBJECT_SCHEMA>(
714
721
  mediaUrl,
715
722
  MEDIA_OBJECT_SCHEMA,
@@ -718,7 +725,7 @@ export class GraffitiDecentralized implements Graffiti {
718
725
 
719
726
  const { key, type, size } = object.value;
720
727
 
721
- if (accept?.maxBytes && size > accept.maxBytes) {
728
+ if (accept?.maxBytes !== undefined && size > accept.maxBytes) {
722
729
  throw new GraffitiErrorTooLarge("File size exceeds limit");
723
730
  }
724
731
 
package/src/index.spec.ts CHANGED
@@ -13,7 +13,7 @@ import { Authorization } from "./1-services/1-authorization";
13
13
  import { StorageBuckets } from "./1-services/3-storage-buckets";
14
14
  import { Inboxes } from "./1-services/4-inboxes";
15
15
  import { Sessions } from "./3-protocol/1-sessions";
16
- import { afterAll, describe } from "vitest";
16
+ import { afterAll, beforeAll, describe } from "vitest";
17
17
  import { Handles } from "./3-protocol/2-handles";
18
18
  import { didTests } from "./1-services/2-dids-tests";
19
19
  import { storageBucketTests } from "./1-services/3-storage-buckets-tests";
@@ -25,48 +25,55 @@ import { allowedAttestationTests } from "./2-primitives/4-allowed-attestations-t
25
25
  import { handleTests } from "./3-protocol/2-handles-tests";
26
26
  import { objectEncodingTests } from "./3-protocol/3-object-encoding-tests";
27
27
  import { GraffitiDecentralized } from "./3-protocol/4-graffiti";
28
+ import {
29
+ DecentralizedTestEnvironment,
30
+ decentralizedSharedInbox,
31
+ decentralizedTestUsers,
32
+ } from "../test/environment";
28
33
 
29
- describe("GraffitiDecentralized Tests", async () => {
30
- // Initialize structures for log in/out
31
- const dids = new DecentralizedIdentifiers();
32
- const sessionMethods = new Sessions({
33
- dids,
34
- authorization: new Authorization(),
35
- inboxes: new Inboxes(),
36
- storageBuckets: new StorageBuckets(),
37
- });
38
- const handleMethods = new Handles({ dids });
39
-
40
- // Login
41
- const handles = [
42
- "localhost%3A5173:app:handles:handle:test1",
43
- "localhost%3A5173:app:handles:handle:test2",
44
- ];
34
+ describe("GraffitiDecentralized Tests", () => {
35
+ const environment = new DecentralizedTestEnvironment();
36
+ const handles = decentralizedTestUsers.map((user) => user.handle);
45
37
  let sessions: GraffitiSession[] = [];
46
- for (const handle of handles) {
47
- sessions.push(await login(handle));
48
- }
49
- const resolvedSessions = sessions.map((s) => {
50
- const resolved = sessionMethods.resolveSession(s);
51
- if (!resolved) throw new Error("Error logging in");
52
- return resolved;
38
+ let sessionMethods: Sessions;
39
+ let handleMethods: Handles;
40
+
41
+ beforeAll(async () => {
42
+ await environment.start();
43
+
44
+ const dids = new DecentralizedIdentifiers();
45
+ sessionMethods = new Sessions({
46
+ dids,
47
+ authorization: new Authorization(),
48
+ inboxes: new Inboxes(),
49
+ storageBuckets: new StorageBuckets(),
50
+ });
51
+ handleMethods = new Handles({ dids });
52
+
53
+ for (const handle of handles) {
54
+ sessions.push(await login(handle));
55
+ }
53
56
  });
54
- // Logout on cleanup
57
+
55
58
  afterAll(async () => {
56
- for (const session of sessions) {
57
- await logout(session.actor);
59
+ try {
60
+ for (const session of sessions) {
61
+ await logout(session.actor);
62
+ }
63
+ } finally {
64
+ await environment.stop();
58
65
  }
59
66
  });
60
67
 
61
68
  // Service tests
62
69
  didTests();
63
70
  storageBucketTests(
64
- resolvedSessions[0].storageBucket.serviceEndpoint,
65
- resolvedSessions[0].storageBucket.token,
71
+ decentralizedTestUsers[0].bucketEndpoint,
72
+ decentralizedTestUsers[0].token,
66
73
  );
67
74
  inboxTests(
68
- resolvedSessions[0].personalInbox.serviceEndpoint,
69
- resolvedSessions[0].personalInbox.token,
75
+ decentralizedTestUsers[0].inboxEndpoint,
76
+ decentralizedTestUsers[0].token,
70
77
  );
71
78
 
72
79
  // Primitive tests
@@ -79,13 +86,10 @@ describe("GraffitiDecentralized Tests", async () => {
79
86
  handleTests(handles[0]);
80
87
  objectEncodingTests();
81
88
 
82
- const useGraffiti = () => {
83
- return new GraffitiDecentralized(
84
- {
85
- defaultInboxEndpoints: ["https://localhost:5173/i/shared"],
86
- },
87
- );
88
- };
89
+ const useGraffiti = () =>
90
+ new GraffitiDecentralized({
91
+ defaultInboxEndpoints: [decentralizedSharedInbox],
92
+ });
89
93
  graffitiCRUDTests(
90
94
  useGraffiti,
91
95
  () => sessions[0],
@@ -107,9 +111,16 @@ describe("GraffitiDecentralized Tests", async () => {
107
111
  const actor = await handleMethods.handleToActor(handle);
108
112
 
109
113
  return await new Promise<GraffitiSession>((resolve, reject) => {
114
+ let timeout: ReturnType<typeof setTimeout>;
115
+ const cleanup = () => {
116
+ clearTimeout(timeout);
117
+ sessionMethods.sessionEvents.removeEventListener("login", listener);
118
+ };
110
119
  const listener = (e: unknown) => {
111
120
  if (!(e instanceof CustomEvent)) return;
112
121
  const detail = e.detail as GraffitiLoginEvent["detail"];
122
+ if (detail.session?.actor !== actor) return;
123
+ cleanup();
113
124
  if (detail.error) {
114
125
  reject(detail.error);
115
126
  } else {
@@ -118,23 +129,30 @@ describe("GraffitiDecentralized Tests", async () => {
118
129
  };
119
130
  sessionMethods.sessionEvents.addEventListener("login", listener);
120
131
 
121
- setTimeout(
132
+ timeout = setTimeout(
122
133
  () => {
123
- sessionMethods.sessionEvents.removeEventListener("login", listener);
134
+ cleanup();
124
135
  reject(new Error("Authorization timed out"));
125
136
  },
126
- 5 * 60 * 1000,
127
- ); // 5 minutes timeout
137
+ 30 * 1000,
138
+ );
128
139
 
129
- sessionMethods.login(actor);
140
+ void sessionMethods.login(actor);
130
141
  });
131
142
  }
132
143
 
133
144
  async function logout(actor: string) {
134
145
  return await new Promise<void>((resolve, reject) => {
146
+ let timeout: ReturnType<typeof setTimeout>;
147
+ const cleanup = () => {
148
+ clearTimeout(timeout);
149
+ sessionMethods.sessionEvents.removeEventListener("logout", listener);
150
+ };
135
151
  const listener = (e: unknown) => {
136
152
  if (!(e instanceof CustomEvent)) return;
137
153
  const detail = e.detail as GraffitiLogoutEvent["detail"];
154
+ if (detail.actor !== actor) return;
155
+ cleanup();
138
156
 
139
157
  if (detail.error) {
140
158
  reject(detail.error);
@@ -144,15 +162,15 @@ describe("GraffitiDecentralized Tests", async () => {
144
162
  };
145
163
  sessionMethods.sessionEvents.addEventListener("logout", listener);
146
164
 
147
- setTimeout(
165
+ timeout = setTimeout(
148
166
  () => {
149
- sessionMethods.sessionEvents.removeEventListener("logout", listener);
167
+ cleanup();
150
168
  reject(new Error("Logout timed out"));
151
169
  },
152
- 5 * 60 * 1000,
153
- ); // 5 minutes timeout
170
+ 30 * 1000,
171
+ );
154
172
 
155
- sessionMethods.logout(actor);
173
+ void sessionMethods.logout(actor);
156
174
  });
157
175
  }
158
176
  });
package/src/index.ts CHANGED
@@ -1,4 +1,5 @@
1
- import { Graffiti, GraffitiRuntimeTypes } from "@graffiti-garden/api";
1
+ import type { Graffiti } from "@graffiti-garden/api";
2
+ import { GraffitiRuntimeTypes } from "@graffiti-garden/wrapper-runtime-types";
2
3
  import {
3
4
  GraffitiDecentralized as GraffitiDecentralized_,
4
5
  type GraffitiDecentralizedOptions,
@@ -1,2 +0,0 @@
1
- export declare function didTests(): import("vitest").SuiteCollector<object>;
2
- //# sourceMappingURL=2-dids-tests.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"2-dids-tests.d.ts","sourceRoot":"","sources":["../../src/1-services/2-dids-tests.ts"],"names":[],"mappings":"AAGA,wBAAgB,QAAQ,4CAoBvB"}
@@ -1,2 +0,0 @@
1
- export declare function storageBucketTests(storageBucketEndpoint: string, storageBucketToken: string): void;
2
- //# sourceMappingURL=3-storage-buckets-tests.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"3-storage-buckets-tests.d.ts","sourceRoot":"","sources":["../../src/1-services/3-storage-buckets-tests.ts"],"names":[],"mappings":"AAKA,wBAAgB,kBAAkB,CAChC,qBAAqB,EAAE,MAAM,EAC7B,kBAAkB,EAAE,MAAM,QAiH3B"}
@@ -1,2 +0,0 @@
1
- export declare function inboxTests(inboxEndpoint: string, inboxToken: string): void;
2
- //# sourceMappingURL=4-inboxes-tests.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"4-inboxes-tests.d.ts","sourceRoot":"","sources":["../../src/1-services/4-inboxes-tests.ts"],"names":[],"mappings":"AAMA,wBAAgB,UAAU,CAAC,aAAa,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,QAqJnE"}
@@ -1,2 +0,0 @@
1
- export declare function stringEncodingTests(): void;
2
- //# sourceMappingURL=1-string-encoding-tests.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"1-string-encoding-tests.d.ts","sourceRoot":"","sources":["../../src/2-primitives/1-string-encoding-tests.ts"],"names":[],"mappings":"AAOA,wBAAgB,mBAAmB,SAyBlC"}
@@ -1,2 +0,0 @@
1
- export declare function contentAddressesTests(): void;
2
- //# sourceMappingURL=2-content-addresses-tests.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"2-content-addresses-tests.d.ts","sourceRoot":"","sources":["../../src/2-primitives/2-content-addresses-tests.ts"],"names":[],"mappings":"AAOA,wBAAgB,qBAAqB,SAsCpC"}
@@ -1,2 +0,0 @@
1
- export declare function channelAttestationTests(): void;
2
- //# sourceMappingURL=3-channel-attestations-tests.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"3-channel-attestations-tests.d.ts","sourceRoot":"","sources":["../../src/2-primitives/3-channel-attestations-tests.ts"],"names":[],"mappings":"AAWA,wBAAgB,uBAAuB,SAiHtC"}
@@ -1,2 +0,0 @@
1
- export declare function allowedAttestationTests(): void;
2
- //# sourceMappingURL=4-allowed-attestations-tests.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"4-allowed-attestations-tests.d.ts","sourceRoot":"","sources":["../../src/2-primitives/4-allowed-attestations-tests.ts"],"names":[],"mappings":"AAWA,wBAAgB,uBAAuB,SA0EtC"}
@@ -1,2 +0,0 @@
1
- export declare function handleTests(handle: string): void;
2
- //# sourceMappingURL=2-handles-tests.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"2-handles-tests.d.ts","sourceRoot":"","sources":["../../src/3-protocol/2-handles-tests.ts"],"names":[],"mappings":"AAIA,wBAAgB,WAAW,CAAC,MAAM,EAAE,MAAM,QAYzC"}
@@ -1,2 +0,0 @@
1
- export declare function objectEncodingTests(): void;
2
- //# sourceMappingURL=3-object-encoding-tests.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"3-object-encoding-tests.d.ts","sourceRoot":"","sources":["../../src/3-protocol/3-object-encoding-tests.ts"],"names":[],"mappings":"AA2BA,wBAAgB,mBAAmB,SAiPlC"}