@@ -346,6 +346,166 @@ It is recommended to set a default `user-agent` header for Node.js
346
346
applications. The default for the default Node.js document loader is
347
347
` jsonld.js ` .
348
348
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
+
349
509
Related Modules
350
510
---------------
351
511
0 commit comments