@graffiti-garden/api 0.6.4 → 1.0.1

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 (44) hide show
  1. package/README.md +0 -7
  2. package/dist/index.cjs +1 -1
  3. package/dist/index.cjs.map +4 -4
  4. package/dist/index.mjs +1 -1
  5. package/dist/index.mjs.map +4 -4
  6. package/dist/src/1-api.d.ts +172 -178
  7. package/dist/src/1-api.d.ts.map +1 -1
  8. package/dist/src/2-types.d.ts +39 -152
  9. package/dist/src/2-types.d.ts.map +1 -1
  10. package/dist/src/3-errors.d.ts +2 -8
  11. package/dist/src/3-errors.d.ts.map +1 -1
  12. package/dist/src/4-utilities.d.ts +8 -0
  13. package/dist/src/4-utilities.d.ts.map +1 -0
  14. package/dist/src/index.d.ts +1 -0
  15. package/dist/src/index.d.ts.map +1 -1
  16. package/dist/tests/crud.d.ts +1 -1
  17. package/dist/tests/crud.d.ts.map +1 -1
  18. package/dist/tests/discover.d.ts +1 -1
  19. package/dist/tests/discover.d.ts.map +1 -1
  20. package/dist/tests/index.d.ts +1 -2
  21. package/dist/tests/index.d.ts.map +1 -1
  22. package/dist/tests/media.d.ts +3 -0
  23. package/dist/tests/media.d.ts.map +1 -0
  24. package/dist/tests/utils.d.ts +3 -3
  25. package/dist/tests/utils.d.ts.map +1 -1
  26. package/dist/tests.mjs +207 -790
  27. package/dist/tests.mjs.map +4 -4
  28. package/package.json +6 -6
  29. package/src/1-api.ts +182 -186
  30. package/src/2-types.ts +42 -157
  31. package/src/3-errors.ts +6 -22
  32. package/src/4-utilities.ts +65 -0
  33. package/src/index.ts +1 -0
  34. package/tests/crud.ts +39 -332
  35. package/tests/discover.ts +51 -349
  36. package/tests/index.ts +1 -2
  37. package/tests/media.ts +158 -0
  38. package/tests/utils.ts +4 -4
  39. package/dist/tests/channel-stats.d.ts +0 -3
  40. package/dist/tests/channel-stats.d.ts.map +0 -1
  41. package/dist/tests/orphans.d.ts +0 -3
  42. package/dist/tests/orphans.d.ts.map +0 -1
  43. package/tests/channel-stats.ts +0 -129
  44. package/tests/orphans.ts +0 -128
package/src/1-api.ts CHANGED
@@ -2,12 +2,9 @@ import type {
2
2
  GraffitiObjectUrl,
3
3
  GraffitiObject,
4
4
  GraffitiObjectBase,
5
- GraffitiPatch,
6
5
  GraffitiSession,
7
- GraffitiPutObject,
6
+ GraffitiPostObject,
8
7
  GraffitiObjectStream,
9
- ChannelStats,
10
- GraffitiChannelStatsStream,
11
8
  GraffitiObjectStreamContinue,
12
9
  } from "./2-types";
13
10
  import type { JSONSchema } from "json-schema-to-ts";
@@ -44,14 +41,13 @@ import type { JSONSchema } from "json-schema-to-ts";
44
41
  * ## API Overview
45
42
  *
46
43
  * The Graffiti API provides applications with methods for {@link login} and {@link logout},
47
- * methods to store data objects using standard database operations ({@link put}, {@link get}, {@link patch}, and {@link delete}),
48
- * and a method to {@link discover} data objects from other people.
44
+ * methods to interact with data objects using standard database operations ({@link post}, {@link get}, and {@link delete}),
45
+ * and a method to {@link discover} data objects created by others.
49
46
  * These data objects have a couple structured properties:
50
47
  * - {@link GraffitiObjectBase.url | `url`} (string): A globally unique identifier and locator for the object.
51
48
  * - {@link GraffitiObjectBase.actor | `actor`} (string): An unforgeable identifier for the creator of the object.
52
- * - {@link GraffitiObjectBase.allowed | `allowed`} (string[] | undefined): An array of the identities who are allowed to access the object (undefined for public objects).
49
+ * - {@link GraffitiObjectBase.allowed | `allowed`} (string[] | undefined): An array of the actors who are allowed to access the object (undefined for public objects).
53
50
  * - {@link GraffitiObjectBase.channels | `channels`} (string[]): An array of the *contexts* in which the object should appear.
54
- * - {@link GraffitiObjectBase.lastModified | `revision`} (number): A number to compare different versions of an object.
55
51
  *
56
52
  * All other data is stored in the object's unstructured {@link GraffitiObjectBase.value | `value`} property.
57
53
  * This data can be used to represent social artifacts (e.g. posts, profiles) and activities (e.g. likes, follows).
@@ -99,59 +95,52 @@ import type { JSONSchema } from "json-schema-to-ts";
99
95
  * which are Graffiti's means of organizing data contextually, and a concept called "total reification",
100
96
  * which handles explains how moderation, collaboration, and other interactions are managed.
101
97
  *
102
- * @groupDescription CRUD Methods
103
- * Methods for {@link put | creating}, {@link get | reading}, {@link patch | updating},
98
+ * @groupDescription 1 - Single-Object Methods
99
+ * Methods for {@link post | creating}, {@link get | reading},
104
100
  * and {@link delete | deleting} {@link GraffitiObjectBase | Graffiti objects}.
105
- * @groupDescription Query Methods
101
+ * @groupDescription 2 - Multi-Object Methods
106
102
  * Methods that retrieve or accumulate information about multiple {@link GraffitiObjectBase | Graffiti objects} at a time.
107
- * @groupDescription Session Management
103
+ * @groupDescription 3 - Media Methods
104
+ * Methods for {@link postMedia | creating}, {@link getMedia | reading},
105
+ * and {@link deleteMedia | deleting} media data.
106
+ * @groupDescription 4 - Identity Methods
108
107
  * Methods and properties for logging in and out.
109
108
  */
110
109
  export abstract class Graffiti {
111
110
  /**
112
- * Creates a new {@link GraffitiObjectBase | object} or replaces an existing object.
113
- * An object can only be replaced by the same {@link GraffitiObjectBase.actor | `actor`}
114
- * that created it.
111
+ * Creates a new {@link GraffitiObjectBase | object}.
115
112
  *
116
- * Replacement occurs when the {@link GraffitiObjectBase.url | `url`} of
117
- * the replaced object exactly matches an existing object's URL.
113
+ * @returns Returns the object that has been posted, complete with its
114
+ * assigned {@link GraffitiObjectBase.url | `url`} and
115
+ * {@link GraffitiObjectBase.actor | `actor`}.
118
116
  *
119
- * @throws {@link GraffitiErrorNotFound} if a {@link GraffitiObjectBase.url | `url`}
120
- * is provided that has not been created yet or the {@link GraffitiObjectBase.actor | `actor`}
121
- * is not {@link GraffitiObjectBase.allowed | `allowed`} to see it.
122
- *
123
- * @throws {@link GraffitiErrorForbidden} if the {@link GraffitiObjectBase.actor | `actor`}
124
- * is not the same `actor` as the one who created the object.
125
- *
126
- * @returns Returns the object that was replaced if one one exists, otherwise returns an object with
127
- * with an empty {@link GraffitiObjectBase.value | `value`},
128
- * {@link GraffitiObjectBase.channels | `channels`}, and {@link GraffitiObjectBase.allowed | `allowed`}
129
- * list.
130
- * The {@link GraffitiObjectBase.lastModified | `lastModified`} property of the returned object
131
- * will be updated to the time of replacement/creation.
132
- *
133
- * @group CRUD Methods
117
+ * @group 1 - Single-Object Methods
134
118
  */
135
- abstract put<Schema extends JSONSchema>(
119
+ abstract post<Schema extends JSONSchema>(
136
120
  /**
137
- * The object to be put. This object is statically type-checked against the [JSON schema](https://json-schema.org/) that can be optionally provided
138
- * as the generic type parameter. We highly recommend providing a schema to
139
- * ensure that the put object matches subsequent {@link get} or {@link discover}
121
+ * An object to post, minus its {@link GraffitiObjectBase.url | `url`} and
122
+ * {@link GraffitiObjectBase.actor | `actor`}, which will be assigned once posted.
123
+ * This object is statically type-checked against the [JSON schema](https://json-schema.org/) that can be optionally provided
124
+ * as the generic type parameter. It is recommended to a schema to
125
+ * ensure that the posted object matches subsequent {@link get} or {@link discover}
140
126
  * methods.
141
127
  */
142
- object: GraffitiPutObject<Schema>,
128
+ partialObject: GraffitiPostObject<Schema>,
143
129
  /**
144
130
  * An implementation-specific object with information to authenticate the
145
131
  * {@link GraffitiObjectBase.actor | `actor`}.
146
132
  */
147
133
  session: GraffitiSession,
148
- ): Promise<GraffitiObjectBase>;
134
+ ): Promise<
135
+ GraffitiPostObject<Schema> & {
136
+ url: string;
137
+ actor: string;
138
+ }
139
+ >;
149
140
 
150
141
  /**
151
- * Retrieves an object from a given {@link GraffitiObjectBase.url | `url`}.
152
- *
153
- * The retrieved object is type-checked against the provided [JSON schema](https://json-schema.org/)
154
- * otherwise a {@link GraffitiErrorSchemaMismatch} is thrown.
142
+ * Retrieves an object from a given {@link GraffitiObjectBase.url | `url`} matching
143
+ * the provided `schema`.
155
144
  *
156
145
  * If the retreiving {@link GraffitiObjectBase.actor | `actor`} is not
157
146
  * the object's `actor`,
@@ -166,7 +155,7 @@ export abstract class Graffiti {
166
155
  *
167
156
  * @throws {@link GraffitiErrorSchemaMismatch} if the retrieved object does not match the provided schema.
168
157
  *
169
- * @group CRUD Methods
158
+ * @group 1 - Single-Object Methods
170
159
  */
171
160
  abstract get<Schema extends JSONSchema>(
172
161
  /**
@@ -187,61 +176,18 @@ export abstract class Graffiti {
187
176
  ): Promise<GraffitiObject<Schema>>;
188
177
 
189
178
  /**
190
- * Patches an existing object at a given {@link GraffitiObjectBase.url | `url`}.
191
- * The patching {@link GraffitiObjectBase.actor | `actor`} must be the same as the
192
- * `actor` that created the object.
193
- *
194
- * @returns Returns the original object prior to the patch with its
195
- * {@link GraffitiObjectBase.lastModified | `lastModified`}
196
- * property updated to the time of patching.
197
- *
198
- * @throws {@link GraffitiErrorNotFound} if the object does not exist, has already been deleted,
199
- * or the actor is not {@link GraffitiObjectBase.allowed | `allowed`} to access it.
200
- *
201
- * @throws {@link GraffitiErrorForbidden} if the {@link GraffitiObjectBase.actor | `actor`}
202
- * is not the same `actor` as the one who created the object.
203
- *
204
- * @group CRUD Methods
205
- */
206
- abstract patch(
207
- /**
208
- * A collection of [JSON Patch](https://jsonpatch.com) operations
209
- * to apply to the object. See {@link GraffitiPatch} for more information.
210
- */
211
- patch: GraffitiPatch,
212
- /**
213
- * The location of the object to patch.
214
- */
215
- url: string | GraffitiObjectUrl,
216
- /**
217
- * An implementation-specific object with information to authenticate the
218
- * {@link GraffitiObjectBase.actor | `actor`}.
219
- */
220
- session: GraffitiSession,
221
- ): Promise<GraffitiObjectBase>;
222
-
223
- /**
224
- * Deletes an object from a given {@link GraffitiObjectBase.url | `url`}.
179
+ * Deletes an object from a given {@link GraffitiObjectBase.url | `url`}
180
+ * that had previously been {@link post | `post`ed}.
225
181
  * The deleting {@link GraffitiObjectBase.actor | `actor`} must be the same as the
226
182
  * `actor` that created the object.
227
183
  *
228
- * It is not possible to re-{@link put} an object that has been deleted
229
- * to ensure a person's [right to be forgotten](https://en.wikipedia.org/wiki/Right_to_be_forgotten).
230
- * In cases where deleting and restoring an object is useful, an object's
231
- * {@link GraffitiObjectBase.allowed | `allowed`} property can be set to
232
- * an empty list to hide it from all actors except the creator.
233
- *
234
- * @returns Returns the object that was deleted with its
235
- * {@link GraffitiObjectBase.lastModified | `lastModified`}
236
- * property updated to the time of deletion.
237
- *
238
- * @throws {@link GraffitiErrorNotFound} if the object does not exist, has already been deleted,
184
+ * @throws {@link GraffitiErrorNotFound} if the object does not exist, has already been deleted,
239
185
  * or the actor is not {@link GraffitiObjectBase.allowed | `allowed`} to access it.
240
186
  *
241
187
  * @throws {@link GraffitiErrorForbidden} if the {@link GraffitiObjectBase.actor | `actor`}
242
188
  * is not the same `actor` as the one who created the object.
243
189
  *
244
- * @group CRUD Methods
190
+ * @group 1 - Single-Object Methods
245
191
  */
246
192
  abstract delete(
247
193
  /**
@@ -253,7 +199,7 @@ export abstract class Graffiti {
253
199
  * {@link GraffitiObjectBase.actor | `actor`}.
254
200
  */
255
201
  session: GraffitiSession,
256
- ): Promise<GraffitiObjectBase>;
202
+ ): Promise<void>;
257
203
 
258
204
  /**
259
205
  * Discovers objects created by any actor that are contained
@@ -270,7 +216,7 @@ export abstract class Graffiti {
270
216
  * string can be serialized to continue the stream after an application is closed
271
217
  * and reopened.
272
218
  *
273
- * `discover` will not return objects that the {@link GraffitiObjectBase.actor | `actor`}
219
+ * `discover` will not return objects that the querying {@link GraffitiObjectBase.actor | `actor`}
274
220
  * is not {@link GraffitiObjectBase.allowed | `allowed`} to access.
275
221
  * If the `actor` is not the creator of a discovered object,
276
222
  * the allowed list will be masked to only contain the querying actor if the
@@ -281,14 +227,11 @@ export abstract class Graffiti {
281
227
  *
282
228
  * Since different implementations may fetch data from multiple sources there is
283
229
  * no guarentee on the order that objects are returned in.
284
- * It is also possible that duplicate objects are returned and their
285
- * {@link GraffitiObjectBase.lastModified | `lastModified`} fields must be used
286
- * to determine which object is the most recent.
287
230
  *
288
231
  * @returns Returns a stream of objects that match the given {@link GraffitiObjectBase.channels | `channels`}
289
232
  * and [JSON Schema](https://json-schema.org).
290
233
  *
291
- * @group Query Methods
234
+ * @group 2 - Multi-Object Methods
292
235
  */
293
236
  abstract discover<Schema extends JSONSchema>(
294
237
  /**
@@ -309,95 +252,137 @@ export abstract class Graffiti {
309
252
  ): GraffitiObjectStream<Schema>;
310
253
 
311
254
  /**
312
- * Discovers objects **not** contained in any
313
- * {@link GraffitiObjectBase.channels | `channels`}
314
- * that were created by the querying {@link GraffitiObjectBase.actor | `actor`}
315
- * and match the given [JSON Schema](https://json-schema.org).
316
- * Unlike {@link discover}, this method will not return objects created by other actors.
255
+ * Continues a {@link GraffitiObjectStream} from a given
256
+ * {@link GraffitiObjectStreamReturn.cursor | `cursor`} string.
257
+ * The continuation will return new objects that have been {@link post | `post`ed}
258
+ * that match the original stream, and also returns the
259
+ * {@link GraffitiObjectBase.url | `url`}s of objects that
260
+ * have been {@link delete | `delete`d}, as marked by a `tombstone`.
261
+ *
262
+ * The `cursor` allows the client to
263
+ * serialize the state of the stream and continue it later.
264
+ * However this method loses any typing information that was
265
+ * present in the original stream. For better type safety
266
+ * and when serializing is not necessary, use the
267
+ * {@link GraffitiObjectStreamReturn.continue | `continue`} method
268
+ * instead, which is returned along with the `cursor` at the
269
+ * end of the original stream.
317
270
  *
318
- * Like {@link channelStats}, this method is not useful for most applications,
319
- * but necessary for getting a global view of all an actor's Graffiti data
320
- * to implement something like Facebook's Activity Log or a debugging interface.
271
+ * @throws {@link GraffitiErrorForbidden} if the {@link GraffitiObjectBase.actor | `actor`}
272
+ * provided in the `session` is not the same as the `actor`
273
+ * that initiated the original stream.
321
274
  *
322
- * Like {@link discover}, objects are returned asynchronously as they are discovered,
323
- * the stream will end once all leads have been exhausted, and the stream
324
- * can be continued using the {@link GraffitiObjectStreamReturn.continue | `continue`}
325
- * method or {@link GraffitiObjectStreamReturn.cursor | `cursor`} string.
275
+ * @group 2 - Multi-Object Methods
276
+ */
277
+ abstract continueDiscover(
278
+ cursor: string,
279
+ session?: GraffitiSession | null,
280
+ ): GraffitiObjectStreamContinue<{}>;
281
+
282
+ /**
283
+ * Uploads media data, such as an image or video.
326
284
  *
327
- * @returns Returns a stream of objects created by the querying {@link GraffitiObjectBase.actor | `actor`}
328
- * that do not belong to any {@link GraffitiObjectBase.channels | `channels`}
329
- * and match the given [JSON Schema](https://json-schema.org).
285
+ * Unlike structured {@link GraffitiObjectBase | objects},
286
+ * media is not indexed for {@link discover | `discover`y} and
287
+ * must be retrieved by its exact URL using {@link getMedia}
330
288
  *
331
- * @group Query Methods
289
+ * @returns The URL that the media was posted to.
290
+ *
291
+ * @group 3 - Media Methods
332
292
  */
333
- abstract recoverOrphans<Schema extends JSONSchema>(
334
- /**
335
- * A [JSON Schema](https://json-schema.org) that orphaned objects must satisfy.
336
- */
337
- schema: Schema,
293
+ abstract postMedia(
294
+ media: {
295
+ /**
296
+ * The binary data of the media to be uploaded,
297
+ * along with its [media type](https://www.iana.org/assignments/media-types/media-types.xhtml),
298
+ * formatted as a [Blob](https://developer.mozilla.org/en-US/docs/Web/API/Blob).
299
+ */
300
+ data: Blob;
301
+ /**
302
+ * An optional list, identical in function to an object's
303
+ * {@link GraffitiObjectBase.allowed | `allowed`} property,
304
+ * that specifies the {@link GraffitiObjectBase.actor | `actor`}s
305
+ * who are allowed to access the media. If the list is `undefined`
306
+ * or `null`, anyone with the URL can access the media. If the list
307
+ * is empty, only the {@link GraffitiObjectBase.actor | `actor`}
308
+ * who {@link postMedia | `post`ed} the media can access it.
309
+ */
310
+ allowed?: string[] | null;
311
+ },
338
312
  /**
339
313
  * An implementation-specific object with information to authenticate the
340
314
  * {@link GraffitiObjectBase.actor | `actor`}.
341
315
  */
342
316
  session: GraffitiSession,
343
- ): GraffitiObjectStream<Schema>;
317
+ ): Promise<string>;
344
318
 
345
319
  /**
346
- * Returns statistics about all the {@link GraffitiObjectBase.channels | `channels`}
347
- * that an {@link GraffitiObjectBase.actor | `actor`} has posted to.
348
- * This method will not return statistics related to any other actor's channel usage.
349
- *
350
- * Like {@link recoverOrphans}, this method is not useful for most applications,
351
- * but necessary for getting a global view of all an actor's Graffiti data
352
- * to implement something like Facebook's Activity Log or a debugging interface.
320
+ * Deletes media previously {@link postMedia | `post`ed} to a given URL.
353
321
  *
354
- * Like {@link discover}, objects are returned asynchronously as they are discovered and
355
- * the stream will end once all leads have been exhausted.
322
+ * @throws {@link GraffitiErrorNotFound} if no media at that URL exists.
356
323
  *
357
- * @group Query Methods
324
+ * @throws {@link GraffitiErrorForbidden} if the {@link GraffitiObjectBase.actor | `actor`}
325
+ * provided in the `session` is not the same as the `actor` that {@link postMedia | `post`ed}
326
+ * the media.
358
327
  *
359
- * @returns Returns a stream of statistics for each {@link GraffitiObjectBase.channels | `channel`}
360
- * that the {@link GraffitiObjectBase.actor | `actor`} has posted to.
328
+ * @group 3 - Media Methods
361
329
  */
362
- abstract channelStats(
330
+ abstract deleteMedia(
331
+ /**
332
+ * A globally unique identifier and locator for the media.
333
+ */
334
+ mediaUrl: string,
363
335
  /**
364
336
  * An implementation-specific object with information to authenticate the
365
337
  * {@link GraffitiObjectBase.actor | `actor`}.
366
338
  */
367
339
  session: GraffitiSession,
368
- ): GraffitiChannelStatsStream;
340
+ ): Promise<void>;
369
341
 
370
342
  /**
371
- * Continues a {@link GraffitiObjectStream} from a given
372
- * {@link GraffitiObjectStreamReturn.cursor | `cursor`} string.
373
- * The continuation will return new objects that have been created
374
- * that match the original stream, and also returns the
375
- * {@link GraffitiObjectBase.url | `url`}s of objects that
376
- * have been deleted, as marked by a `tombstone`.
343
+ * Retrieves media from the given media URL, adhering to the given requirements.
377
344
  *
378
- * The continuation may also include duplicates of objects that
379
- * were already returned by the original stream. This is dependent
380
- * on how much state the underlying implementation maintains.
345
+ * @throws {@link GraffitiErrorNotFound} if no media at that URL exists.
381
346
  *
382
- * The `cursor` allows the client to
383
- * serialize the state of the stream and continue it later.
384
- * However this method loses any typing information that was
385
- * present in the original stream. For better type safety
386
- * and when serializing is not necessary, use the
387
- * {@link GraffitiObjectStreamReturn.continue | `continue`} method
388
- * instead, which is returned along with the `cursor` at the
389
- * end of the original stream.
347
+ * @throws {@link GraffitiErrorTooLarge} if the media exceeds the given `maxBytes`.
390
348
  *
391
- * @throws {@link GraffitiErrorForbidden} if the {@link GraffitiObjectBase.actor | `actor`}
392
- * provided in the `session` is not the same as the `actor`
393
- * that initiated the original stream.
349
+ * @throws {@link GraffitiErrorNotAcceptable} if the media does not match the given
350
+ * `accept` specification.
394
351
  *
395
- * @group Query Methods
352
+ * @returns The URL of the retrieved media, as a [Blob](https://developer.mozilla.org/en-US/docs/Web/API/Blob)
353
+ * and the {@link GraffitiObjectBase.actor | `actor`} that posted it.
354
+ *
355
+ * @group 3 - Media Methods
396
356
  */
397
- abstract continueObjectStream(
398
- cursor: string,
357
+ abstract getMedia(
358
+ /**
359
+ * A globally unique identifier and locator for the media.
360
+ */
361
+ mediaUrl: string,
362
+ /**
363
+ * A set of requirements the retrieved media must meet.
364
+ */
365
+ requirements: {
366
+ /**
367
+ * A list of acceptable media types for the retrieved media,
368
+ * formatted as like an [HTTP Accept header](https://httpwg.org/specs/rfc9110.html#field.accept)
369
+ */
370
+ accept?: string;
371
+ /**
372
+ * The maximum acceptable size, in bytes, of the media.
373
+ */
374
+ maxBytes?: number;
375
+ },
376
+ /**
377
+ * An implementation-specific object with information to authenticate the
378
+ * {@link GraffitiObjectBase.actor | `actor`}.
379
+ */
399
380
  session?: GraffitiSession | null,
400
- ): GraffitiObjectStreamContinue<{}>;
381
+ ): Promise<{
382
+ data: Blob;
383
+ actor: string;
384
+ allowed?: string[] | null;
385
+ }>;
401
386
 
402
387
  /**
403
388
  * Begins the login process. Depending on the implementation, this may
@@ -409,38 +394,19 @@ export abstract class Graffiti {
409
394
  * asynchronously via {@link Graffiti.sessionEvents | sessionEvents}
410
395
  * as a {@link GraffitiLoginEvent} with event type `login`.
411
396
  *
412
- * @group Session Management
397
+ * @group 4 - Identity Methods
413
398
  */
414
399
  abstract login(
415
400
  /**
416
- * Suggestions for the permissions that the
417
- * login process should grant. The login process may not
418
- * provide the exact proposed permissions.
401
+ * A suggested actor to login as. For example, if a user tries to
402
+ * edit a post but are not logged in, the interface can infer that
403
+ * they might want to log in as the actor who created the post
404
+ * they are attempting to edit.
405
+ *
406
+ * Even if provided, the implementation should allow the user
407
+ * to log in as a different actor if they choose.
419
408
  */
420
- proposal?: {
421
- /**
422
- * A suggested actor to login as. For example, if a user tries to
423
- * edit a post but are not logged in, the interface can infer that
424
- * they might want to log in as the actor who created the post
425
- * they are attempting to edit.
426
- *
427
- * Even if provided, the implementation should allow the user
428
- * to log in as a different actor if they choose.
429
- */
430
- actor?: string;
431
- /**
432
- * A yet to be defined permissions scope. An application may use
433
- * this to indicate the minimum necessary scope needed to
434
- * operate. For example, it may need to be able read private
435
- * messages from a certain set of channels, or write messages that
436
- * follow a particular schema.
437
- *
438
- * The login process should make it clear what scope an application
439
- * is requesting and allow the user to enhance or reduce that
440
- * scope as necessary.
441
- */
442
- scope?: {};
443
- },
409
+ actor?: string,
444
410
  ): Promise<void>;
445
411
 
446
412
  /**
@@ -453,7 +419,7 @@ export abstract class Graffiti {
453
419
  * {@link Graffiti.sessionEvents | sessionEvents}
454
420
  * as a {@link GraffitiLogoutEvent} as event type `logout`.
455
421
  *
456
- * @group Session Management
422
+ * @group 4 - Identity Methods
457
423
  */
458
424
  abstract logout(
459
425
  /**
@@ -469,7 +435,37 @@ export abstract class Graffiti {
469
435
  * - `logout` - {@link GraffitiLogoutEvent}
470
436
  * - `initialized` - {@link GraffitiSessionInitializedEvent}
471
437
  *
472
- * @group Session Management
438
+ * @group 4 - Identity Methods
473
439
  */
474
440
  abstract readonly sessionEvents: EventTarget;
441
+
442
+ /**
443
+ * Retrieves the human-readable handle associated
444
+ * with the given actor. The handle may change over time
445
+ * and so it should be used for display purposes only.
446
+ *
447
+ * The inverse of {@link handleToActor}.
448
+ *
449
+ * @throws {@link GraffitiErrorNotFound} if a handle cannot be
450
+ * found for the given actor.
451
+ *
452
+ * @returns A human-readable handle for the given actor.
453
+ *
454
+ * @group 4 - Identity Methods
455
+ */
456
+ abstract actorToHandle(actor: string): Promise<string>;
457
+
458
+ /**
459
+ * Retrieves the actor ID associated with the given handle.
460
+ *
461
+ * The inverse of {@link actorToHandle}.
462
+ *
463
+ * @throws {@link GraffitiErrorNotFound} if there is no actor
464
+ * with the given handle.
465
+ *
466
+ * @returns The actor ID for the given handle.
467
+ *
468
+ * @group 4 - Identity Methods
469
+ */
470
+ abstract handleToActor(handle: string): Promise<string>;
475
471
  }