@hitchy/plugin-odem-socket.io 0.3.0 → 0.4.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.
@@ -1,8 +1,7 @@
1
- "use strict";
1
+ import { promisify } from "node:util";
2
2
 
3
- const { promisify } = require( "node:util" );
4
-
5
- module.exports = function() {
3
+ /** */
4
+ export default function() {
6
5
  const api = this;
7
6
 
8
7
  const logDebug = api.log( "hitchy:plugin:odem:socket.io:debug" );
@@ -88,7 +87,7 @@ module.exports = function() {
88
87
  .then( item => this.namespaceEmit( namespace, Model, {
89
88
  change: "created",
90
89
  model: Model.name,
91
- properties: item.toObject( { serialized: true } ),
90
+ properties: this.serializeItem( item, false ),
92
91
  }, true ) )
93
92
  .catch( cause => {
94
93
  logError( "broadcasting notification on having created item %s of %s has failed:", uuid, Model.name, cause.stack );
@@ -99,7 +98,7 @@ module.exports = function() {
99
98
  .then( item => this.namespaceEmit( namespace, Model, {
100
99
  change: "updated",
101
100
  model: Model.name,
102
- properties: item.toObject( { serialized: true } ),
101
+ properties: this.serializeItem( item, false ),
103
102
  }, true ) )
104
103
  .catch( cause => {
105
104
  logError( "broadcasting notification on having updated item %s of %s has failed:", uuid, Model.name, cause.stack );
@@ -109,7 +108,7 @@ module.exports = function() {
109
108
  this.namespaceEmit( namespace, Model, {
110
109
  change: "deleted",
111
110
  model: Model.name,
112
- properties: { uuid: Model.formatUUID( uuid ) },
111
+ properties: { uuid: String( uuid ) },
113
112
  }, false )
114
113
  .catch( cause => {
115
114
  logError( "broadcasting notification on having removed item %s of %s has failed:", uuid, Model.name, cause.stack );
@@ -353,7 +352,7 @@ module.exports = function() {
353
352
  let filter;
354
353
 
355
354
  if ( loadRecords ) {
356
- filter = item => api.service.OdemSchema.filterItem( item.toObject( { serialized: true } ), { user }, Model, "list" );
355
+ filter = item => api.service.OdemSchema.filterItem( this.serializeItem( item, false ), { user }, Model, "list" );
357
356
  } else {
358
357
  filter = item => ( { uuid: item.uuid } );
359
358
  }
@@ -405,7 +404,7 @@ module.exports = function() {
405
404
  let filter;
406
405
 
407
406
  if ( loadRecords ) {
408
- filter = item => api.service.OdemSchema.filterItem( item.toObject( { serialized: true } ), { user }, Model, "list" );
407
+ filter = item => api.service.OdemSchema.filterItem( this.serializeItem( item, false ), { user }, Model, "list" );
409
408
  } else {
410
409
  filter = item => ( { uuid: item.uuid } );
411
410
  }
@@ -434,7 +433,7 @@ module.exports = function() {
434
433
  * @returns {Promise<void>} promise settled on request handled
435
434
  */
436
435
  static async handleCreateRequest( socket, Model, properties, response ) {
437
- logDebug( "request for creating %s instance with %j", Model.name, properties );
436
+ logDebug( "request for creating %s instance with %j", Model.name, reduce( properties ) );
438
437
 
439
438
  const { Authorization, OdemSchema } = api.service;
440
439
 
@@ -453,9 +452,9 @@ module.exports = function() {
453
452
  const filtered = OdemSchema.filterItem( properties, { user }, Model, "create" );
454
453
  const instance = new Model();
455
454
 
456
- for ( const [ propName, propValue ] of Object.entries( filtered ) ) {
455
+ for ( const propName of Object.keys( filtered ) ) {
457
456
  if ( schema.props.hasOwnProperty( propName ) || schema.computed.hasOwnProperty( propName ) ) {
458
- instance[propName] = propValue;
457
+ instance[propName] = filtered[propName];
459
458
  }
460
459
  }
461
460
 
@@ -463,7 +462,7 @@ module.exports = function() {
463
462
 
464
463
  response( {
465
464
  success: true,
466
- properties: OdemSchema.filterItem( instance.toObject( { serialized: true } ), { user }, Model, "read" ),
465
+ properties: OdemSchema.filterItem( this.serializeItem( instance, false ), { user }, Model, "read" ),
467
466
  } );
468
467
  } catch ( error ) {
469
468
  logError( "creating %s instance failed: %s", Model.name, error.stack );
@@ -504,7 +503,7 @@ module.exports = function() {
504
503
 
505
504
  response( {
506
505
  success: true,
507
- properties: api.service.OdemSchema.filterItem( instance.toObject( { serialized: true } ), { user }, Model, "read" ),
506
+ properties: api.service.OdemSchema.filterItem( this.serializeItem( instance, true ), { user }, Model, "read" ),
508
507
  } );
509
508
  } catch ( error ) {
510
509
  logError( "reading %s instance failed: %s", Model.name, error.stack );
@@ -526,7 +525,7 @@ module.exports = function() {
526
525
  * @returns {Promise<void>} promise settled on request handled
527
526
  */
528
527
  static async handleUpdateRequest( socket, Model, uuid, properties, response ) {
529
- logDebug( "request for updating %s instance %s with %j", Model.name, uuid, properties );
528
+ logDebug( "request for updating %s instance %s with %j", Model.name, uuid, reduce( properties ) );
530
529
 
531
530
  try {
532
531
  const user = await this.getUserForSocket( socket );
@@ -556,7 +555,7 @@ module.exports = function() {
556
555
 
557
556
  response( {
558
557
  success: true,
559
- properties: api.service.OdemSchema.filterItem( instance.toObject( { serialized: true } ), { user }, Model, "read" ),
558
+ properties: api.service.OdemSchema.filterItem( this.serializeItem( instance, false ), { user }, Model, "read" ),
560
559
  } );
561
560
  } catch ( error ) {
562
561
  logError( "updating %s instance failed: %s", Model.name, error.stack );
@@ -607,6 +606,47 @@ module.exports = function() {
607
606
  } );
608
607
  }
609
608
  }
609
+
610
+ /**
611
+ * Serializes provided instance of a model optionally including/excluding
612
+ * properties marked as _lazy_.
613
+ *
614
+ * This method is used to provide reduced sets of properties per item
615
+ * on listing/updating items while delivering all properties when
616
+ * reading individual items.
617
+ *
618
+ * @param {Hitchy.Plugin.Odem.Model} item instance of model
619
+ * @param {boolean} includeLazyProperties if true, properties marked as lazy in schema of model are included with resulting record
620
+ * @returns {object} record of provided item's serialized properties
621
+ */
622
+ static serializeItem( item, includeLazyProperties = false ) {
623
+ const record = item.toObject( { serialized: true } );
624
+
625
+ if ( includeLazyProperties ) {
626
+ return record;
627
+ }
628
+
629
+ const filtered = {};
630
+
631
+ for ( const name of Object.keys( record ) ) {
632
+ let definition = item.constructor.schema.props[name];
633
+
634
+ if ( definition == null ) {
635
+ definition = item.constructor.schema.computed[name];
636
+ }
637
+
638
+ const lazy = definition?.lazy;
639
+
640
+ if ( !lazy ||
641
+ ( typeof lazy === "string" && lazy !== "ws" && lazy !== "socket" && lazy !== "websocket" ) ||
642
+ ( typeof lazy === "object" && !lazy.ws && !lazy.socket && !lazy.websocket )
643
+ ) {
644
+ filtered[name] = record[name];
645
+ }
646
+ }
647
+
648
+ return filtered;
649
+ }
610
650
  }
611
651
 
612
652
  return OdemWebsocketProvider;
@@ -615,7 +655,7 @@ module.exports = function() {
615
655
  /**
616
656
  * Commonly responds to action requests in case of having disabled them.
617
657
  *
618
- * @param {function(response: any):void} respondFn callback to be invoked for responding to a peer event
658
+ * @param {function(any):void} respondFn callback to be invoked for responding to a peer event
619
659
  * @returns {void}
620
660
  */
621
661
  function reject( respondFn ) {
@@ -623,3 +663,42 @@ function reject( respondFn ) {
623
663
  error: "requested action is not available due to runtime configuration",
624
664
  } );
625
665
  }
666
+
667
+ /**
668
+ * Recursively trims values of provided data.
669
+ *
670
+ * @param {*} data data to be trimmed
671
+ * @param {number} limit number of characters to keep in strings when trimming
672
+ * @returns {*} provided data trimmed as necessary
673
+ */
674
+ function reduce( data, limit = 200 ) {
675
+ if ( Array.isArray( data ) ) {
676
+ return data.map( item => reduce( item, Math.max( 10, limit / 5 ) ) );
677
+ }
678
+
679
+ if ( data && typeof data === "object" ) {
680
+ const copy = {};
681
+
682
+ for ( const name of Object.keys( data ) ) {
683
+ copy[name] = reduce( data[name], Math.max( 10, limit / 5 ) );
684
+ }
685
+
686
+ return copy;
687
+ }
688
+
689
+ switch ( typeof data ) {
690
+ case "function" :
691
+ case "string" : {
692
+ const s = String( data );
693
+
694
+ if ( s.length > limit ) {
695
+ return s.substring( 0, limit ) + "…+" + String( limit - s.length );
696
+ }
697
+
698
+ return s;
699
+ }
700
+
701
+ default :
702
+ return data;
703
+ }
704
+ }
package/config/socket.js CHANGED
@@ -1,6 +1,4 @@
1
- "use strict";
2
-
3
- module.exports = {
1
+ export default {
4
2
  socket: {
5
3
  odem: {
6
4
  /**
package/index.js CHANGED
@@ -1,6 +1,5 @@
1
- "use strict";
2
-
3
- module.exports = function() {
1
+ /** */
2
+ export default function() {
4
3
  const api = this;
5
4
 
6
5
  return {
package/package.json CHANGED
@@ -1,12 +1,13 @@
1
1
  {
2
2
  "name": "@hitchy/plugin-odem-socket.io",
3
- "version": "0.3.0",
3
+ "version": "0.4.0",
4
4
  "description": "exposing Hitchy's document-oriented database via websocket",
5
5
  "main": "index.js",
6
+ "type": "module",
6
7
  "scripts": {
7
8
  "lint": "eslint .",
8
- "test": "hitchy-pm odem socket.io auth --exec mocha --ui=tdd 'test/**/*.spec.js'",
9
- "coverage": "hitchy-pm odem socket.io auth --exec c8 mocha --ui=tdd 'test/**/*.spec.js'"
9
+ "test": "hitchy-pm odem socket.io auth --exec mocha --ui=tdd test/**/*.spec.js",
10
+ "coverage": "hitchy-pm odem socket.io auth --exec c8 mocha --ui=tdd test/**/*.spec.js"
10
11
  },
11
12
  "repository": {
12
13
  "type": "git",
@@ -29,18 +30,18 @@
29
30
  "index.js"
30
31
  ],
31
32
  "peerDependencies": {
32
- "@hitchy/core": ">=0.8.1",
33
- "@hitchy/plugin-odem": ">=0.9.1",
34
- "@hitchy/plugin-socket.io": ">=0.1.1"
33
+ "@hitchy/core": "1.x",
34
+ "@hitchy/plugin-odem": "0.13.x",
35
+ "@hitchy/plugin-socket.io": "0.1.x"
35
36
  },
36
37
  "devDependencies": {
37
- "@hitchy/server-dev-tools": "^0.4.9",
38
- "c8": "^10.1.2",
39
- "eslint": "^8.57.0",
40
- "eslint-config-cepharum": "^1.0.14",
41
- "eslint-plugin-promise": "^7.1.0",
42
- "mocha": "^10.7.3",
38
+ "@hitchy/server-dev-tools": "^0.8.6",
39
+ "c8": "^10.1.3",
40
+ "eslint": "^9.23.0",
41
+ "eslint-config-cepharum": "^2.0.2",
42
+ "eslint-plugin-promise": "^7.2.1",
43
+ "mocha": "^11.1.0",
43
44
  "should": "^13.2.3",
44
- "socket.io-client": "^4.7.5"
45
+ "socket.io-client": "^4.8.1"
45
46
  }
46
47
  }
package/readme.md CHANGED
@@ -59,7 +59,7 @@ socket.on( "connect", () => {
59
59
  } );
60
60
  ```
61
61
 
62
- > socket.io requires all arguments to be provided no matter what. Thus, you can't omit any of the arguments given in examples below but have to provide values assumed to be default, at least.
62
+ > socket.io requires all arguments to be provided no matter what. Thus, you can not omit any of the arguments given in examples below but have to provide values assumed to be default, at least.
63
63
 
64
64
  The following code excerpts are focusing on the inner part of emitting an action event and processing the response.
65
65