Skip to content

Commit 81e2775

Browse files
committed
Add events docs.
- Marked as experimental.
1 parent 06aae7d commit 81e2775

File tree

1 file changed

+160
-0
lines changed

1 file changed

+160
-0
lines changed

README.md

Lines changed: 160 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -346,6 +346,166 @@ It is recommended to set a default `user-agent` header for Node.js
346346
applications. The default for the default Node.js document loader is
347347
`jsonld.js`.
348348

349+
### Events
350+
351+
**WARNING**: This feature is **experimental** and the API, events, codes,
352+
levels, and messages may change.
353+
354+
Various events may occur during processing. The event handler system allows
355+
callers to handle events as appropriate. Use cases can be as simple as logging
356+
warnings, to displaying helpful UI hints, to failing on specific conditions.
357+
358+
**Note**: By default no event handler is used. This is due to general
359+
performance considerations and the impossibility of providing a default handler
360+
that would work for all use cases. Event construction and the handling system
361+
are avoided by default providing the best performance for use cases where data
362+
quality is known events are unnecessary.
363+
364+
#### Event Structure
365+
366+
Events are basic JSON objects with the following properties:
367+
368+
- **`code`**: A basic string code, similar to existing JSON-LD error codes.
369+
- **`level`**: The severity level. Currently only `warning` is emitted.
370+
- **`tags`**: Optional hints for the type of event. Currently defined:
371+
- **`unsafe`**: Event is considered unsafe.
372+
- **`lossy`**: Event is related to potential data loss.
373+
- **`empty`**: Event is related to empty data structures.
374+
- **`message`**: A human readable message describing the event.
375+
- **`details`**: A JSON object with event specific details.
376+
377+
#### Event Handlers
378+
379+
Event handlers are chainable functions, arrays of handlers, objects mapping
380+
codes to handlers, or any mix of these structures. Each function is passed an
381+
object with two properties:
382+
383+
- **`event`**: The event data.
384+
- **`next`**: A function to call to an `event` and a `next`.
385+
386+
The event handling system will process the handler structure, calling all
387+
handlers, and continuing onto the next handler if `next()` is called. To stop
388+
processing, throw an error, or return without calling `next()`.
389+
390+
This design allows for composable handler structures, for instance to handle
391+
some conditions with a custom handler, and default to generic "unknown event"
392+
or logging handler.
393+
394+
**Note**: Handlers are currently synchronous due to possible performance
395+
issues. This may change to an `async`/`await` design in the future.
396+
397+
```js
398+
// expand a document with a logging event handler
399+
const expanded = await jsonld.expand(data, {
400+
// simple logging handler
401+
eventHandler: function({event, next}) {
402+
console.log('event', {event});
403+
}
404+
});
405+
```
406+
407+
```js
408+
function logEventHandler({event, next}) {
409+
console.log('event', {event});
410+
next();
411+
}
412+
413+
function noWarningsEventHandler({event, next}) {
414+
if(event.level === 'warning') {
415+
throw new Error('No warnings!', {event});
416+
}
417+
next();
418+
}
419+
420+
function unknownEventHandler({event, next}) {
421+
throw new Error('Unknown event', {event});
422+
}
423+
424+
// expand a document with an array of event handlers
425+
const expanded = await jsonld.expand(data, {
426+
// array of handlers
427+
eventHandler: [
428+
logEventHandler,
429+
noWarningsEventHandler,
430+
unknownEventHandler
431+
]}
432+
});
433+
```
434+
435+
```js
436+
const handler = {
437+
'a mild event code': function({event}) {
438+
console.log('the thing happened', {event});
439+
},
440+
'a serious event code': function({event}) {
441+
throw new Error('the specific thing happened', {event});
442+
}
443+
};
444+
// expand a document with a code map event handler
445+
const expanded = await jsonld.expand(data, {eventHandler});
446+
```
447+
448+
#### Safe Mode
449+
450+
A common use case is to avoid JSON-LD constructs that will result in lossy
451+
behavior. The JSON-LD specifications have notes about when data is dropped.
452+
This can be especially important when calling [`canonize`][] in order to
453+
digitally sign data. The event system can be used to detect and avoid these
454+
situations. A special "safe mode" is available that will inject an initial
455+
event handler that fails on conditions that would result in data loss. More
456+
benign events may fall back to the passed event handler, if any.
457+
458+
**Note**: This mode is designed to be the common way that digital signing and
459+
similar applications use this library.
460+
461+
The `safe` options flag set to `true` enables this behavior:
462+
463+
```js
464+
// expand a document in safe mode
465+
const expanded = await jsonld.expand(data, {safe: true});
466+
```
467+
468+
```js
469+
// expand a document in safe mode, with fallback handler
470+
const expanded = await jsonld.expand(data, {
471+
safe: true
472+
eventHandler: function({event}) { /* ... */ }
473+
});
474+
```
475+
476+
#### Available Handlers
477+
478+
Some predefined event handlers are available to use alone or as part of a more
479+
complex handler:
480+
481+
- **safeModeEventHandler**: The handler used when `safe` is `true`.
482+
- **strictModeEventHandler**: A handler that is more strict than the `safe`
483+
handler and also fails on other detectable events related to poor input
484+
structure.
485+
- **logEventHandler**: A debugging handler that outputs to the console.
486+
- **logWarningHandler**: A debugging handler that outputs `warning` level
487+
events to the console.
488+
- **unhandledEventHandler**: Throws on all events not yet handled.
489+
490+
#### Default Event Handler
491+
492+
A default event handler can be set. It will be the only handler when not in
493+
safe mode, and the second handler when in safe mode.
494+
495+
```js
496+
// fail on unknown events
497+
jsonld.setDefaultEventHandler(jsonld.unhandledEventHandler);
498+
// will use safe mode handler, like `{safe: true}`
499+
const expanded = await jsonld.expand(data);
500+
```
501+
502+
```js
503+
// always use safe mode event handler, ignore other events
504+
jsonld.setDefaultEventHandler(jsonld.safeModeEventHandler);
505+
// will use safe mode handler, like `{safe: true}`
506+
const expanded = await jsonld.expand(data);
507+
```
508+
349509
Related Modules
350510
---------------
351511

0 commit comments

Comments
 (0)