@graffiti-garden/api 0.6.4 → 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.
package/src/2-types.ts CHANGED
@@ -1,23 +1,23 @@
1
1
  import type { JSONSchema, FromSchema } from "json-schema-to-ts";
2
- import type { Operation as JSONPatchOperation } from "fast-json-patch";
3
2
 
4
3
  /**
5
4
  * Objects are the atomic unit in Graffiti that can represent both data (*e.g.* a social media post or profile)
6
5
  * and activities (*e.g.* a like or follow).
7
- * Objects are created and modified by a single {@link actor | `actor`}.
8
6
  *
9
- * Most of an object's content is stored in its {@link value | `value`} property, which can be any JSON
10
- * object. However, we recommend using properties from the
7
+ * Each object embeds the {@link actor | `actor`} that created it.
8
+ * Object content and metadata are static but an object may be deleted by
9
+ * its creating {@link actor | `actor`}.
10
+ *
11
+ * An object's content is stored in its {@link value | `value`} property, which can be any JSON
12
+ * object. However, it is recommended to use properties from the
11
13
  * [Activity Vocabulary](https://www.w3.org/TR/activitystreams-vocabulary/)
12
14
  * or properties that emerge in the Graffiti [folksonomy](https://en.wikipedia.org/wiki/Folksonomy)
13
15
  * to promote interoperability.
14
16
  *
15
- * The object is globally addressable via its {@link url | `url`}.
16
- *
17
- * The {@link channels | `channels`} and {@link allowed | `allowed`} properties
18
- * enable the object's creator to shape the visibility of and access to their object.
17
+ * Each object is globally addressable via its {@link url | `url`}.
19
18
  *
20
- * The {@link lastModified | `lastModified`} property can be used to compare object versions.
19
+ * An object's {@link channels | `channels`} and {@link allowed | `allowed`} properties
20
+ * are set by an objects creator to shape the visibility of and access to their object.
21
21
  */
22
22
  export interface GraffitiObjectBase {
23
23
  /**
@@ -34,11 +34,11 @@ export interface GraffitiObjectBase {
34
34
  * {@link Graffiti.discover} method. This allows creators to express the intended audience of their object
35
35
  * which helps to prevent [context collapse](https://en.wikipedia.org/wiki/Context_collapse) even
36
36
  * in the highly interoperable ecosystem that Graffiti envisions. For example, channel URIs may be:
37
- * - A actor's own {@link actor | `actor`} URI. Putting an object in this channel is a way to broadcast
37
+ * - A actor's own {@link actor | `actor`} URI. Posting an object to this channel is a way to broadcast
38
38
  * the object to the actor's followers, like posting a tweet.
39
- * - The URL of a Graffiti post. Putting an object in this channel is a way to broadcast to anyone viewing
39
+ * - The URL of a Graffiti post. Posting an object to this channel is a way to broadcast to anyone viewing
40
40
  * the post, like commenting on a tweet.
41
- * - A URI representing a topic. Putting an object in this channel is a way to broadcast to anyone interested
41
+ * - A URI representing a topic. Posting an object to this channel is a way to broadcast to anyone interested
42
42
  * in that topic, like posting in a subreddit.
43
43
  */
44
44
  channels: string[];
@@ -54,14 +54,15 @@ export interface GraffitiObjectBase {
54
54
  * other recipients, however this is not enforced by Graffiti and may not accurately reflect the actual `allowed` array.
55
55
  *
56
56
  * `allowed` can be combined with {@link channels | `channels`}. For example, to send someone a direct message
57
- * the sender should put their object in the channel of the recipient's {@link actor | `actor`} URI to notify them of the message and also add
57
+ * the sender should post their object to the channel of the recipient's {@link actor | `actor`} URI to notify them of the message and also add
58
58
  * the recipient's {@link actor | `actor`} URI to the `allowed` array to prevent others from seeing the message.
59
59
  */
60
60
  allowed?: string[] | null;
61
61
 
62
62
  /**
63
- * The URI of the `actor` that {@link Graffiti.put | created } the object. This `actor` also has the unique permission to
64
- * {@link Graffiti.patch | modify} or {@link Graffiti.delete | delete} the object.
63
+ * The URI of the `actor` that {@link Graffiti.post | created } the object.
64
+ * This `actor` has the unique permission to
65
+ * {@link Graffiti.delete | delete} the object.
65
66
  *
66
67
  * We borrow the term actor from the ActivityPub because
67
68
  * [like in ActivityPub](https://www.w3.org/TR/activitypub/#h-note-0)
@@ -77,8 +78,6 @@ export interface GraffitiObjectBase {
77
78
  /**
78
79
  * A globally unique identifier and locator for the object. It can be used to point to
79
80
  * an object or to retrieve the object directly with {@link Graffiti.get}.
80
- * If an object is {@link Graffiti.put | put} with the same URL
81
- * as an existing object, the existing object will be replaced with the new object.
82
81
  *
83
82
  * An object's URL is generated when the object is first created and
84
83
  * should include sufficient randomness to prevent collisions
@@ -92,25 +91,6 @@ export interface GraffitiObjectBase {
92
91
  * or `graffiti:p2p:` for objects stored on a peer-to-peer network.
93
92
  */
94
93
  url: string;
95
-
96
- /**
97
- * A number used to compare different versions of an object that has been
98
- * updated via replacement (see {@link Graffiti.put}) or
99
- * patch (see {@link Graffiti.patch}). Newer versions of
100
- * an object have larger `revision` values than older versions.
101
- * The `revision` can only
102
- * be used to compare different versions of the same object,
103
- * but cannot reliably be used to compare different objects.
104
- * In cases where comparing different objects by time is useful,
105
- * you could instead add `createdAt` or `lastModified` timestamp properties
106
- * to an object's {@link value | `value`}.
107
- *
108
- * Depending on the implementation, the revision may be a timestamp,
109
- * an incremental counter, may include randomness for obfuscation, and so on.
110
- * Be careful not to rely on any of these specific `revision` instantiations
111
- * as they may not be consistent across different implementations.
112
- */
113
- lastModified: number;
114
94
  }
115
95
 
116
96
  /**
@@ -137,48 +117,43 @@ export const GraffitiObjectJSONSchema = {
137
117
  allowed: { type: "array", items: { type: "string" }, nullable: true },
138
118
  url: { type: "string" },
139
119
  actor: { type: "string" },
140
- lastModified: { type: "number" },
141
120
  },
142
121
  additionalProperties: false,
143
- required: ["value", "channels", "actor", "url", "lastModified"],
122
+ required: ["value", "channels", "actor", "url"],
144
123
  } as const satisfies JSONSchema;
145
124
 
146
125
  /**
147
126
  * This is an object containing only the {@link GraffitiObjectBase.url | `url`}
148
127
  * property of a {@link GraffitiObjectBase | GraffitiObject}.
149
- * It is used as a utility type so that applications can call {@link Graffiti.get},
150
- * {@link Graffiti.patch}, or {@link Graffiti.delete} directly on an object
128
+ * It is used as a utility type so that applications can call
129
+ * {@link Graffiti.delete} directly on an object
151
130
  * rather than on `object.url`.
152
131
  */
153
132
  export type GraffitiObjectUrl = Pick<GraffitiObjectBase, "url">;
154
133
 
155
134
  /**
156
- * This object is a subset of {@link GraffitiObjectBase} that must be constructed locally before calling {@link Graffiti.put}.
157
- * This local copy does not require system-generated properties and may be statically typed with
135
+ * This object is a subset of {@link GraffitiObjectBase} that must be constructed locally before calling {@link Graffiti.post}.
136
+ * This local copy ignores system-generated properties
137
+ * ({@link GraffitiObjectBase.url | `url`} and {@link GraffitiObjectBase.actor | `actor`}),
138
+ * and may be statically typed with
158
139
  * a [JSON schema](https://json-schema.org/) to prevent the accidental creation of erroneous objects.
159
140
  *
160
141
  * This local object must have a {@link GraffitiObjectBase.value | `value`} and {@link GraffitiObjectBase.channels | `channels`}
161
142
  * and may optionally have an {@link GraffitiObjectBase.allowed | `allowed`} property.
162
- *
163
- * It may also include a {@link GraffitiObjectBase.url | `url`} property to specify the
164
- * URL of an existing object to replace. If no `url` is provided, one will be generated during object creation.
165
- *
166
- * This object does not need a {@link GraffitiObjectBase.lastModified | `lastModified`}
167
- * property since it will be automatically generated by the Graffiti system.
168
143
  */
169
- export type GraffitiPutObject<Schema extends JSONSchema> = Pick<
144
+ export type GraffitiPostObject<Schema extends JSONSchema> = Pick<
170
145
  GraffitiObjectBase,
171
146
  "value" | "channels" | "allowed"
172
147
  > &
173
148
  Partial<GraffitiObjectBase> &
174
- FromSchema<Schema & typeof GraffitiPutObjectJSONSchema>;
149
+ FromSchema<Schema & typeof GraffitiPostObjectJSONSchema>;
175
150
 
176
151
  /**
177
- * A JSON Schema equivalent to the {@link GraffitiPutObject} type.
152
+ * A JSON Schema equivalent to the {@link GraffitiPostObject} type.
178
153
  * Needed internally for type inference of JSON Schemas, but can
179
154
  * be used by implementations to validate objects.
180
155
  */
181
- export const GraffitiPutObjectJSONSchema = {
156
+ export const GraffitiPostObjectJSONSchema = {
182
157
  ...GraffitiObjectJSONSchema,
183
158
  required: ["value", "channels"],
184
159
  } as const satisfies JSONSchema;
@@ -187,7 +162,7 @@ export const GraffitiPutObjectJSONSchema = {
187
162
  * This object contains information that the underlying implementation can
188
163
  * use to authenticate a particular {@link GraffitiObjectBase.actor | `actor`}.
189
164
  * This object is required of all {@link Graffiti} methods
190
- * that modify objects and is optional for methods that read objects.
165
+ * that modify objects or media and is optional for methods that read objects.
191
166
  *
192
167
  * At a minimum the `session` object must contain the
193
168
  * {@link GraffitiSession.actor | `actor`} URI to authenticate with.
@@ -205,9 +180,6 @@ export const GraffitiPutObjectJSONSchema = {
205
180
  * with {@link Graffiti.get} and {@link Graffiti.discover} but without type-checking
206
181
  * the `session` it can be easy to forget to hide buttons that trigger
207
182
  * other methods that require login.
208
- * In the future, `session` object may be updated to include scope information
209
- * and passing the `session` to each method can type-check whether the session provides the
210
- * necessary permissions.
211
183
  *
212
184
  * Passing the `session` object per-method also allows for multiple sessions
213
185
  * to be used within the same application, like an Email client fetching from
@@ -218,58 +190,17 @@ export interface GraffitiSession {
218
190
  * The {@link GraffitiObjectBase.actor | `actor`} to authenticate with.
219
191
  */
220
192
  actor: string;
221
- /**
222
- * A yet undefined property detailing what operations the session
223
- * grants the actor to perform. For example, to allow a actor to
224
- * read private messages from a particular set of channels or
225
- * to allow the actor to write object matching a particular schema.
226
- */
227
- scope?: {};
228
- }
229
-
230
- /**
231
- * This is the format for patches that modify {@link GraffitiObjectBase} objects
232
- * using the {@link Graffiti.patch} method. The patches must
233
- * be an array of [JSON Patch](https://jsonpatch.com) operations.
234
- * Patches can only be applied to the
235
- * {@link GraffitiObjectBase.value | `value`}, {@link GraffitiObjectBase.channels | `channels`},
236
- * and {@link GraffitiObjectBase.allowed | `allowed`} properties since the other
237
- * properties either describe the object's location or are automatically generated.
238
- * (See also {@link GraffitiPutObject}).
239
- */
240
- export interface GraffitiPatch {
241
- /**
242
- * An array of [JSON Patch](https://jsonpatch.com) operations to
243
- * modify the object's {@link GraffitiObjectBase.value | `value`}. The resulting
244
- * `value` must still be a JSON object.
245
- */
246
- value?: JSONPatchOperation[];
247
-
248
- /**
249
- * An array of [JSON Patch](https://jsonpatch.com) operations to
250
- * modify the object's {@link GraffitiObjectBase.channels | `channels`}. The resulting
251
- * `channels` must still be an array of strings.
252
- */
253
- channels?: JSONPatchOperation[];
254
-
255
- /**
256
- * An array of [JSON Patch](https://jsonpatch.com) operations to
257
- * modify the object's {@link GraffitiObjectBase.allowed | `allowed`} property. The resulting
258
- * `allowed` property must still be an array of strings or `undefined`.
259
- */
260
- allowed?: JSONPatchOperation[];
261
193
  }
262
194
 
263
195
  /**
264
- * A stream of data that are returned by Graffiti's query-like operations
265
- * {@link Graffiti.discover} and {@link Graffiti.recoverOrphans}.
196
+ * A stream of data that are returned by {@link Graffiti.discover}.
266
197
  *
267
198
  * Errors are returned within the stream rather than as
268
199
  * exceptions that would halt the entire stream. This is because
269
200
  * some implementations may pull data from multiple sources
270
201
  * including some that may be unreliable. In many cases,
271
202
  * these errors can be safely ignored.
272
- * See {@link GraffitiStreamError}.
203
+ * See {@link GraffitiObjectStreamError}.
273
204
  *
274
205
  * The stream is an [`AsyncGenerator`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function)
275
206
  * that can be iterated over using `for await` loops or calling `next` on the generator.
@@ -280,17 +211,16 @@ export interface GraffitiPatch {
280
211
  * each of which can be used to resume the stream from where it left off.
281
212
  */
282
213
  export type GraffitiObjectStream<Schema extends JSONSchema> = AsyncGenerator<
283
- GraffitiStreamError | GraffitiObjectStreamEntry<Schema>,
214
+ GraffitiObjectStreamError | GraffitiObjectStreamEntry<Schema>,
284
215
  GraffitiObjectStreamReturn<Schema>
285
216
  >;
286
217
 
287
218
  /**
288
- * An error that can occur in either the
289
- * {@link GraffitiObjectStream} or {@link GraffitiChannelStatsStream}.
219
+ * An error that can occur in a {@link GraffitiObjectStream}.
290
220
  *
291
221
  * @internal
292
222
  */
293
- export interface GraffitiStreamError {
223
+ export interface GraffitiObjectStreamError {
294
224
  /**
295
225
  * The error that occurred while streaming data.
296
226
  */
@@ -311,7 +241,7 @@ export interface GraffitiStreamError {
311
241
  */
312
242
  export interface GraffitiObjectStreamEntry<Schema extends JSONSchema> {
313
243
  /**
314
- * Empty property for compatibility with {@link GraffitiStreamError}
244
+ * Empty property for compatibility with {@link GraffitiObjectStreamError}
315
245
  */
316
246
  error?: undefined;
317
247
  /**
@@ -334,7 +264,7 @@ export interface GraffitiObjectStreamEntry<Schema extends JSONSchema> {
334
264
  */
335
265
  export interface GraffitiObjectStreamContinueTombstone {
336
266
  /**
337
- * Empty property for compatibility with {@link GraffitiStreamError}
267
+ * Empty property for compatibility with {@link GraffitiObjectStreamError}
338
268
  */
339
269
  error?: undefined;
340
270
  /**
@@ -344,25 +274,13 @@ export interface GraffitiObjectStreamContinueTombstone {
344
274
  tombstone: true;
345
275
  /**
346
276
  * Sparse metadata about the deleted object. The full object is not returned
347
- * to respect a actor's privacy.
277
+ * to respect an actor's privacy.
348
278
  */
349
279
  object: {
350
280
  /**
351
281
  * The {@link GraffitiObjectBase.url | `url`} of the deleted object.
352
282
  */
353
283
  url: string;
354
- /**
355
- * The time at which the object was deleted, comparable to
356
- * {@link GraffitiObjectBase.lastModified | `lastModified`}.
357
- *
358
- * While it is not possible to re-{@link Graffiti.put | put} objects that have been
359
- * {@link Graffiti.delete | deleted}, objects may appear deleted if
360
- * an {@link GraffitiObjectBase.actor | `actor`} is no longer
361
- * {@link GraffitiObjectBase.allowed | `allowed`} to access them.
362
- * Therefore the {@link GraffitiObjectBase.lastModified | `lastModified`} property
363
- * is necessary to compare object versions.
364
- */
365
- lastModified: number;
366
284
  };
367
285
  }
368
286
 
@@ -400,7 +318,7 @@ export interface GraffitiObjectStreamReturn<Schema extends JSONSchema> {
400
318
  continue: () => GraffitiObjectStreamContinue<Schema>;
401
319
  /**
402
320
  * A string that can be serialized and stored to resume the stream later.
403
- * It must be passed to the {@link Graffiti.continueObjectStream} method
321
+ * It must be passed to the {@link Graffiti.continueDiscover} method
404
322
  * to resume the stream.
405
323
  */
406
324
  cursor: string;
@@ -409,7 +327,7 @@ export interface GraffitiObjectStreamReturn<Schema extends JSONSchema> {
409
327
  /**
410
328
  * A continutation of the {@link GraffitiObjectStream} type, as returned by
411
329
  * the {@link GraffitiObjectStreamReturn.continue} or by using
412
- * {@link GraffitiObjectStreamReturn.cursor} with {@link Graffiti.continueObjectStream}.
330
+ * {@link GraffitiObjectStreamReturn.cursor} with {@link Graffiti.continueDiscover}.
413
331
  *
414
332
  * The continued stream may include `tombstone`s of objects that have been
415
333
  * deleted since the original stream was run. See {@link GraffitiObjectStreamContinueTombstone}.
@@ -418,45 +336,10 @@ export interface GraffitiObjectStreamReturn<Schema extends JSONSchema> {
418
336
  */
419
337
  export type GraffitiObjectStreamContinue<Schema extends JSONSchema> =
420
338
  AsyncGenerator<
421
- GraffitiStreamError | GraffitiObjectStreamContinueEntry<Schema>,
339
+ GraffitiObjectStreamError | GraffitiObjectStreamContinueEntry<Schema>,
422
340
  GraffitiObjectStreamReturn<Schema>
423
341
  >;
424
342
 
425
- /**
426
- * Statistic about single channel returned by {@link Graffiti.channelStats}.
427
- * These statistics only account for contributions made by the
428
- * querying actor.
429
- */
430
- export type ChannelStats = {
431
- /**
432
- * The URI of the channel.
433
- */
434
- channel: string;
435
- /**
436
- * The number of objects that the actor has {@link Graffiti.put | put}
437
- * and not {@link Graffiti.delete | deleted} in the channel.
438
- */
439
- count: number;
440
- /**
441
- * The time that the actor {@link GraffitiObjectBase.lastModified | last modified} an object in the channel,
442
- * measured in milliseconds since January 1, 1970.
443
- * {@link Graffiti.delete | Deleted} objects do not effect this modification time.
444
- */
445
- lastModified: number;
446
- };
447
-
448
- /**
449
- * A stream of data that are returned by Graffiti's {@link Graffiti.channelStats} method.
450
- * See {@link GraffitiObjectStream} for more information on streams.
451
- */
452
- export type GraffitiChannelStatsStream = AsyncGenerator<
453
- | GraffitiStreamError
454
- | {
455
- error?: undefined;
456
- value: ChannelStats;
457
- }
458
- >;
459
-
460
343
  /**
461
344
  * The event type produced in {@link Graffiti.sessionEvents}
462
345
  * when a actor logs in manually from {@link Graffiti.login}
package/src/3-errors.ts CHANGED
@@ -38,19 +38,19 @@ export class GraffitiErrorSchemaMismatch extends Error {
38
38
  }
39
39
  }
40
40
 
41
- export class GraffitiErrorPatchTestFailed extends Error {
41
+ export class GraffitiErrorTooLarge extends Error {
42
42
  constructor(message?: string) {
43
43
  super(message);
44
- this.name = "GraffitiErrorPatchTestFailed";
45
- Object.setPrototypeOf(this, GraffitiErrorPatchTestFailed.prototype);
44
+ this.name = "GraffitiErrorTooLarge";
45
+ Object.setPrototypeOf(this, GraffitiErrorTooLarge.prototype);
46
46
  }
47
47
  }
48
48
 
49
- export class GraffitiErrorPatchError extends Error {
49
+ export class GraffitiErrorNotAcceptable extends Error {
50
50
  constructor(message?: string) {
51
51
  super(message);
52
- this.name = "GraffitiErrorPatchError";
53
- Object.setPrototypeOf(this, GraffitiErrorPatchError.prototype);
52
+ this.name = "GraffitiErrorNotAcceptable";
53
+ Object.setPrototypeOf(this, GraffitiErrorNotAcceptable.prototype);
54
54
  }
55
55
  }
56
56