@furo/open-models 1.15.1 → 1.15.3
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/custom-elements.json +69 -69
- package/dist/FieldNode.d.ts +3 -3
- package/dist/FieldNode.js.map +1 -1
- package/dist/decorators/FieldBindings.d.ts +1 -1
- package/dist/decorators/FieldBindings.js.map +1 -1
- package/dist/decorators/ModelDecorators.d.ts +6 -7
- package/dist/decorators/ModelDecorators.js +4 -4
- package/dist/decorators/ModelDecorators.js.map +1 -1
- package/dist/decorators/ServiceDecorators.d.ts +4 -4
- package/dist/decorators/ServiceDecorators.js +4 -4
- package/dist/decorators/ServiceDecorators.js.map +1 -1
- package/dist/index.d.ts +1 -2
- package/dist/index.js.map +1 -1
- package/package.json +5 -1
- /package/dist/decorators/{defaultServiceEventHandlers.d.ts → DefaultServiceEventHandlers.d.ts} +0 -0
- /package/dist/decorators/{defaultServiceEventHandlers.js → DefaultServiceEventHandlers.js} +0 -0
- /package/dist/decorators/{defaultServiceEventHandlers.js.map → DefaultServiceEventHandlers.js.map} +0 -0
package/custom-elements.json
CHANGED
|
@@ -1209,6 +1209,73 @@
|
|
|
1209
1209
|
"declarations": [],
|
|
1210
1210
|
"exports": []
|
|
1211
1211
|
},
|
|
1212
|
+
{
|
|
1213
|
+
"kind": "javascript-module",
|
|
1214
|
+
"path": "dist/decorators/DefaultServiceEventHandlers.js",
|
|
1215
|
+
"declarations": [
|
|
1216
|
+
{
|
|
1217
|
+
"kind": "function",
|
|
1218
|
+
"name": "DefaultServiceEventHandlers",
|
|
1219
|
+
"parameters": [
|
|
1220
|
+
{
|
|
1221
|
+
"name": "dispatch",
|
|
1222
|
+
"description": "Function to dispatch events (typically bound to the service's dispatchEvent)"
|
|
1223
|
+
},
|
|
1224
|
+
{
|
|
1225
|
+
"name": "options",
|
|
1226
|
+
"default": "{}",
|
|
1227
|
+
"description": "Optional configuration"
|
|
1228
|
+
}
|
|
1229
|
+
],
|
|
1230
|
+
"description": "### DefaultServiceEventHandlers\n\nCreates default service handlers that dispatch standard events.\nUse this to reduce boilerplate when setting up service handlers.\n\nThe `onResponse` handler is intentionally NOT included - you must provide your own\nimplementation since response handling is typically service-specific.\n\nUsage:\n```typescript\nclass MyEntityService extends EventTarget {\n private dispatch = createDispatch(this);\n\n setupHandlers() {\n this.service.Get.setHandlers({\n ...DefaultServiceEventHandlers(this.dispatch),\n onResponse: (response, serverResponse) => {\n // Your custom response handling\n this.entity.fromLiteral(response.entity);\n this.dispatch(\"response-received\", { response, serverResponse });\n },\n });\n }\n}\n```\n\nWith loading check:\n```typescript\nthis.service.Get.setHandlers({\n ...DefaultServiceEventHandlers(this.dispatch, {\n isLoading: () => this.service.Get.isLoading || this.service.Update.isLoading,\n }),\n onResponse: (response, serverResponse) => { ... },\n});\n```",
|
|
1231
|
+
"return": {
|
|
1232
|
+
"type": {
|
|
1233
|
+
"text": ""
|
|
1234
|
+
}
|
|
1235
|
+
}
|
|
1236
|
+
},
|
|
1237
|
+
{
|
|
1238
|
+
"kind": "function",
|
|
1239
|
+
"name": "CreateDispatch",
|
|
1240
|
+
"parameters": [
|
|
1241
|
+
{
|
|
1242
|
+
"name": "target",
|
|
1243
|
+
"description": "The EventTarget to dispatch events on"
|
|
1244
|
+
}
|
|
1245
|
+
],
|
|
1246
|
+
"description": "### createDispatch\n\nHelper to create a typed dispatch function for an EventTarget.\n\nUsage:\n```typescript\nclass MyService extends EventTarget {\n private dispatch = createDispatch(this);\n\n doSomething() {\n this.dispatch(\"busy-changed\", { busy: true });\n }\n}\n```",
|
|
1247
|
+
"return": {
|
|
1248
|
+
"type": {
|
|
1249
|
+
"text": ""
|
|
1250
|
+
}
|
|
1251
|
+
}
|
|
1252
|
+
}
|
|
1253
|
+
],
|
|
1254
|
+
"exports": [
|
|
1255
|
+
{
|
|
1256
|
+
"kind": "js",
|
|
1257
|
+
"name": "DefaultServiceEventHandlers",
|
|
1258
|
+
"declaration": {
|
|
1259
|
+
"name": "DefaultServiceEventHandlers",
|
|
1260
|
+
"module": "dist/decorators/DefaultServiceEventHandlers.js"
|
|
1261
|
+
}
|
|
1262
|
+
},
|
|
1263
|
+
{
|
|
1264
|
+
"kind": "js",
|
|
1265
|
+
"name": "CreateDispatch",
|
|
1266
|
+
"declaration": {
|
|
1267
|
+
"name": "CreateDispatch",
|
|
1268
|
+
"module": "dist/decorators/DefaultServiceEventHandlers.js"
|
|
1269
|
+
}
|
|
1270
|
+
}
|
|
1271
|
+
]
|
|
1272
|
+
},
|
|
1273
|
+
{
|
|
1274
|
+
"kind": "javascript-module",
|
|
1275
|
+
"path": "dist/decorators/DefaultServiceEventHandlers.js.map",
|
|
1276
|
+
"declarations": [],
|
|
1277
|
+
"exports": []
|
|
1278
|
+
},
|
|
1212
1279
|
{
|
|
1213
1280
|
"kind": "javascript-module",
|
|
1214
1281
|
"path": "dist/decorators/EntityServiceTypes.js",
|
|
@@ -1265,7 +1332,7 @@
|
|
|
1265
1332
|
"description": "The FieldNode model to bind to"
|
|
1266
1333
|
}
|
|
1267
1334
|
],
|
|
1268
|
-
"description": "###
|
|
1335
|
+
"description": "### ModelBindings Factory\n\nCreates type-safe decorators bound to a specific FieldNode model.\nUse this to bind component properties and methods to model events.\n\nUsage:\n```typescript\nimport { ModelBindings } from \"@x/furo/open-models/ModelDecorators\";\nimport { CubeEntityModel } from \"./CubeEntityModel\";\n\nconst cubeModel = ModelBindings(CubeEntityModel.model);\n\nclass MyComponent extends LitElement {\n // Bind to a nested field value - updates when cube.length changes",
|
|
1269
1336
|
"return": {
|
|
1270
1337
|
"type": {
|
|
1271
1338
|
"text": ""
|
|
@@ -1382,7 +1449,7 @@
|
|
|
1382
1449
|
"description": "The EventTarget service to bind to"
|
|
1383
1450
|
}
|
|
1384
1451
|
],
|
|
1385
|
-
"description": "###
|
|
1452
|
+
"description": "### ServiceBindings Factory\n\nCreates type-safe decorators bound to a specific service instance.\nUse this to bind component properties and methods to service events.\n\nThe factory is generic and works with any `EventTarget`.\nEvent types and their detail payloads are type-checked at compile time\nvia the `TEventMap` type parameter.\n\nUsage:\n```typescript\nimport { cubeEntityService } from \"./CubeEntityService\";\nimport { ServiceBindings } from \"./ServiceDecorators.js\";\n\nconst cube = ServiceBindings(cubeEntityService);\n\nclass MyComponent extends LitElement {\n // Property binding - type-safe event name, auto-extracts from detail",
|
|
1386
1453
|
"return": {
|
|
1387
1454
|
"type": {
|
|
1388
1455
|
"text": ""
|
|
@@ -1407,73 +1474,6 @@
|
|
|
1407
1474
|
"declarations": [],
|
|
1408
1475
|
"exports": []
|
|
1409
1476
|
},
|
|
1410
|
-
{
|
|
1411
|
-
"kind": "javascript-module",
|
|
1412
|
-
"path": "dist/decorators/defaultServiceEventHandlers.js",
|
|
1413
|
-
"declarations": [
|
|
1414
|
-
{
|
|
1415
|
-
"kind": "function",
|
|
1416
|
-
"name": "DefaultServiceEventHandlers",
|
|
1417
|
-
"parameters": [
|
|
1418
|
-
{
|
|
1419
|
-
"name": "dispatch",
|
|
1420
|
-
"description": "Function to dispatch events (typically bound to the service's dispatchEvent)"
|
|
1421
|
-
},
|
|
1422
|
-
{
|
|
1423
|
-
"name": "options",
|
|
1424
|
-
"default": "{}",
|
|
1425
|
-
"description": "Optional configuration"
|
|
1426
|
-
}
|
|
1427
|
-
],
|
|
1428
|
-
"description": "### DefaultServiceEventHandlers\n\nCreates default service handlers that dispatch standard events.\nUse this to reduce boilerplate when setting up service handlers.\n\nThe `onResponse` handler is intentionally NOT included - you must provide your own\nimplementation since response handling is typically service-specific.\n\nUsage:\n```typescript\nclass MyEntityService extends EventTarget {\n private dispatch = createDispatch(this);\n\n setupHandlers() {\n this.service.Get.setHandlers({\n ...DefaultServiceEventHandlers(this.dispatch),\n onResponse: (response, serverResponse) => {\n // Your custom response handling\n this.entity.fromLiteral(response.entity);\n this.dispatch(\"response-received\", { response, serverResponse });\n },\n });\n }\n}\n```\n\nWith loading check:\n```typescript\nthis.service.Get.setHandlers({\n ...DefaultServiceEventHandlers(this.dispatch, {\n isLoading: () => this.service.Get.isLoading || this.service.Update.isLoading,\n }),\n onResponse: (response, serverResponse) => { ... },\n});\n```",
|
|
1429
|
-
"return": {
|
|
1430
|
-
"type": {
|
|
1431
|
-
"text": ""
|
|
1432
|
-
}
|
|
1433
|
-
}
|
|
1434
|
-
},
|
|
1435
|
-
{
|
|
1436
|
-
"kind": "function",
|
|
1437
|
-
"name": "CreateDispatch",
|
|
1438
|
-
"parameters": [
|
|
1439
|
-
{
|
|
1440
|
-
"name": "target",
|
|
1441
|
-
"description": "The EventTarget to dispatch events on"
|
|
1442
|
-
}
|
|
1443
|
-
],
|
|
1444
|
-
"description": "### createDispatch\n\nHelper to create a typed dispatch function for an EventTarget.\n\nUsage:\n```typescript\nclass MyService extends EventTarget {\n private dispatch = createDispatch(this);\n\n doSomething() {\n this.dispatch(\"busy-changed\", { busy: true });\n }\n}\n```",
|
|
1445
|
-
"return": {
|
|
1446
|
-
"type": {
|
|
1447
|
-
"text": ""
|
|
1448
|
-
}
|
|
1449
|
-
}
|
|
1450
|
-
}
|
|
1451
|
-
],
|
|
1452
|
-
"exports": [
|
|
1453
|
-
{
|
|
1454
|
-
"kind": "js",
|
|
1455
|
-
"name": "DefaultServiceEventHandlers",
|
|
1456
|
-
"declaration": {
|
|
1457
|
-
"name": "DefaultServiceEventHandlers",
|
|
1458
|
-
"module": "dist/decorators/defaultServiceEventHandlers.js"
|
|
1459
|
-
}
|
|
1460
|
-
},
|
|
1461
|
-
{
|
|
1462
|
-
"kind": "js",
|
|
1463
|
-
"name": "CreateDispatch",
|
|
1464
|
-
"declaration": {
|
|
1465
|
-
"name": "CreateDispatch",
|
|
1466
|
-
"module": "dist/decorators/defaultServiceEventHandlers.js"
|
|
1467
|
-
}
|
|
1468
|
-
}
|
|
1469
|
-
]
|
|
1470
|
-
},
|
|
1471
|
-
{
|
|
1472
|
-
"kind": "javascript-module",
|
|
1473
|
-
"path": "dist/decorators/defaultServiceEventHandlers.js.map",
|
|
1474
|
-
"declarations": [],
|
|
1475
|
-
"exports": []
|
|
1476
|
-
},
|
|
1477
1477
|
{
|
|
1478
1478
|
"kind": "javascript-module",
|
|
1479
1479
|
"path": "dist/index.js",
|
package/dist/FieldNode.d.ts
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
*/
|
|
4
4
|
import { ValueState } from './ValueState.js';
|
|
5
5
|
import { FieldConstraints } from './FieldConstraints.js';
|
|
6
|
-
type
|
|
6
|
+
export type ModelEventType = 'update' | 'field-value-changed' | 'this-field-value-changed' | 'field-value-updated' | 'this-state-changed' | 'state-changed' | 'validity-changed' | 'array-changed' | 'this-array-changed' | 'map-changed' | 'this-map-changed' | 'parent-readonly-set' | 'parent-readonly-unset' | 'model-injected';
|
|
7
7
|
type Meta = {
|
|
8
8
|
businessVaueState: ValueState;
|
|
9
9
|
index?: number;
|
|
@@ -351,7 +351,7 @@ export declare abstract class FieldNode {
|
|
|
351
351
|
* @param {function} listener - The object that receives a notification (an object that implements the Event interface) when an event of the specified type occurs. This must be null, an object with a handleEvent() method, or a JavaScript function. See The event listener callback for details on the callback itself.
|
|
352
352
|
* @param {} options - An object that specifies characteristics about the event listener. \n\nThe available option is `once:boolean`
|
|
353
353
|
*/
|
|
354
|
-
__addEventListener(type:
|
|
354
|
+
__addEventListener(type: ModelEventType, listener: CustomEventListener, options?: boolean | AddEventListenerOptions): void;
|
|
355
355
|
__addCustomEventListener(type: string, handler: CustomEventListener, options?: boolean | AddEventListenerOptions): void;
|
|
356
356
|
/**
|
|
357
357
|
* Removes the handler from a node
|
|
@@ -359,7 +359,7 @@ export declare abstract class FieldNode {
|
|
|
359
359
|
* @param handler
|
|
360
360
|
* @param options
|
|
361
361
|
*/
|
|
362
|
-
__removeEventListener(type:
|
|
362
|
+
__removeEventListener(type: ModelEventType, handler: CustomEventListener, options?: boolean | EventListenerOptions): void;
|
|
363
363
|
/**
|
|
364
364
|
* Removes the handler from a node
|
|
365
365
|
* @param type
|
package/dist/FieldNode.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FieldNode.js","sourceRoot":"","sources":["../src/FieldNode.ts"],"names":[],"mappings":"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","sourcesContent":["/* eslint-disable max-classes-per-file, no-use-before-define */\n\n/**\n * notes: i18n is not part of the api anymore\n */\nimport { ValueState } from './ValueState';\nimport { ToString, ValueOf } from './CustomPrototypes';\nimport { CustomConstraints, Validators } from './Validator';\nimport { OPEN_MODELS_OPTIONS } from './OPEN_MODELS_OPTIONS';\nimport { FieldConstraints } from './FieldConstraints';\n\ntype EventType =\n | 'update' // triggered on any change,update,array changes, map changes, reset, model injections, from literal. Listen to this if you do not need specialized update notifications.\n | 'field-value-changed' // triggered on change or value assignment\n | 'this-field-value-changed' // triggered on every direct change on the field, not from children\n | 'field-value-updated' // triggered on clear or fromLiteral => model-injected\n | 'this-state-changed' // triggered when value states are changed\n | 'state-changed' // triggered when value states are changed\n | 'validity-changed'\n | 'array-changed'\n | 'this-array-changed'\n | 'map-changed'\n | 'this-map-changed'\n | 'parent-readonly-set' // fired when a parent was set to *ro*, listen to this event to make your UI element readonly.\n | 'parent-readonly-unset' // fired when a parent was set to *rw*, listen to this event to make your UI element writable, but you have to check for your own *ro state* and any *ro* parent.\n // | 'child-readonly-set' implement this when @maltenorstroem asks for it\n // | 'child-readonly-unset' implement this when @maltenorstroem asks for it\n | 'model-injected'; // fired on the injection node before field-value-updated and this-field-value-changed\n\ntype Meta = {\n businessVaueState: ValueState;\n index?: number;\n oldValue?: unknown;\n initialValue: unknown; // Initial value from __updateWithLiteral\n typeName: string; // i.e \"furo.fat.Bool\"\n fieldName?: string; // field name of this node used by its parent node\n valueState: ValueState;\n stateMessage: string;\n nodeFields: FieldDescriptor[];\n readonly: boolean;\n required: boolean;\n isArrayNode: boolean; // set by array and used by baseName resolver to omit the index in the names\n deleteArrayNode?: () => void; // only available on array nodes\n isRecursionNode: boolean;\n isAnyNode: boolean;\n isValid: boolean;\n isPristine: boolean;\n eventListener: Map<\n string,\n {\n callbackfn: CustomEventListener;\n options?: AddEventListenerOptions | boolean;\n }[]\n >;\n // Description of the message type itself. Used for AI jsonschema generation.\n description?: string;\n};\n\n/**\n * Primitives have always a value field\n */\ninterface IPrimitive extends FieldNode {\n _value: unknown; // contains the value of the FieldNode\n}\n\ninterface CustomEventListener {\n (evt: CustomEvent): void;\n}\n\nexport type FieldDescriptor = {\n // camel case name of the field\n fieldName: string;\n // API name of the field, defined by contract.\n protoName: string;\n // class of the type, must start with cap\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n FieldConstructor: any; // (new(_initData: any, parent?: FieldNode, parentAttributeName?: string) => FieldNode);\n ValueConstructor?: new () => FieldNode; // used by MAP\n constraints?: FieldConstraints;\n // Optional description to generate AI friendly jsonschema\n description?: string;\n};\n\nexport interface ValueStateSummary {\n /**\n * path of the field\n *\n * `fullName` for a violation in the `fullName` value\n * `emailAddresses[1].email` for a violation in the `email` field of the first `emailAddresses` message\n * `emailAddresses[3].type[2]` for a violation in the second `type` value in the third `emailAddresses` message.\n */\n field: string;\n state: ValueState;\n message: string;\n}\n\nexport abstract class FieldNode {\n protected ___isEmpty: boolean = true;\n\n /**\n * Marker for primitive types\n */\n public __isPrimitive: boolean = false;\n\n /**\n * Parent node of a node. This is undefined on root nodes.\n */\n public __parentNode: FieldNode | undefined;\n\n /**\n * Metadata of a field node.\n */\n public __meta: Meta = {\n businessVaueState: ValueState.None,\n readonly: false,\n required: false,\n initialValue: undefined,\n isPristine: true,\n isValid: true,\n valueState: ValueState.None,\n stateMessage: '',\n typeName: '',\n nodeFields: [],\n isArrayNode: false,\n isRecursionNode: false,\n isAnyNode: false,\n eventListener: new Map<string, []>(),\n };\n\n private ___rootNode: FieldNode;\n\n private ___readonlyState: Map<FieldNode, boolean> = new Map<\n FieldNode,\n boolean\n >();\n\n /**\n * Root node of a node\n */\n get __rootNode(): FieldNode {\n return this.___rootNode;\n }\n\n /**\n * Root node of a node. Do not set this value by yourself.\n * @param value\n */\n set __rootNode(value: FieldNode) {\n this.___rootNode = value;\n }\n\n /**\n * Empty state of the node\n */\n get __isEmpty() {\n return this.___isEmpty;\n }\n\n /**\n * Empty state of the node\n * @param empty\n */\n set __isEmpty(empty: boolean) {\n if (empty) {\n this.___isEmpty = true;\n } else {\n this.___updateNotEmptyPath();\n }\n }\n\n constructor(\n _initData: undefined,\n parent?: FieldNode,\n parentAttributeName?: string,\n ) {\n this.__parentNode = parent;\n\n if (parent) {\n this.___rootNode = parent.__rootNode;\n } else {\n this.___rootNode = this;\n }\n\n this.__meta.fieldName = parentAttributeName;\n }\n\n /**\n * Get a FieldNode by giving a field path using the proto names for the fields.\n *\n *\n *\n * - `email_addresses[3].type[2]` for the second `type` value in the third `email_addresses` message.\n * - `user.location.street` for the street in location in user.\n *\n * @param {string} deepPath - Path of the field.\n */\n __getFieldNodeByPath(deepPath: string = ''): FieldNode | undefined {\n // replace array paths\n const path = deepPath.replaceAll(/[[\\]]/g, '.').split('.');\n if (path.length > 0 && path[0] !== '') {\n // rest wieder in error reinwerfen\n // eslint-disable-next-line no-param-reassign\n deepPath = path.slice(1).join('.');\n // convert to camel\n const fieldName = this.__toLowerCamelCase(path[0]) as keyof FieldNode;\n\n if (deepPath === '') {\n if (this[fieldName]) {\n return this[fieldName] as FieldNode;\n }\n } else if (this[fieldName]) {\n return (this[fieldName] as FieldNode).__getFieldNodeByPath(deepPath);\n }\n return undefined;\n }\n return undefined;\n }\n\n /**\n * Check if the node is \"readonly\"\n *\n * When any this node or any parent is *ro*, this will return false.\n *\n */\n public __isLogicalReadonly(): boolean {\n if (this.__readonly) {\n return true;\n }\n if (this.__parentNode) {\n return this.__parentNode.__isLogicalReadonly();\n }\n return false;\n }\n\n /**\n * Set the readonly state\n * @param v\n */\n public set __readonly(v: boolean) {\n // to save resources, we could check for __isReadonly and fire the event based on this\n this.__meta.readonly = v;\n // dispatch to children\n this.__broadcastEvent(\n new CustomEvent(v ? 'parent-readonly-set' : 'parent-readonly-unset', {\n detail: this,\n bubbles: false,\n }),\n );\n }\n\n get __readonly(): boolean {\n return this.__meta.readonly;\n }\n\n /**\n * Build up the model with the literal type. The literal type matches the interface from ITypeName.\n * @param {} literal - The literal type matches the interface from ITypeName.\n */\n __fromLiteral(literal: unknown) {\n this.__updateWithLiteral(literal);\n // clear the state of the validity and value state\n this.__setModelValidStateTrue();\n\n this.__dispatchEvent(\n new CustomEvent('model-injected', {\n composed: true,\n bubbles: false,\n detail: this,\n }),\n );\n\n this.__meta.isPristine = true;\n // this.__notifyFieldValueChange(true);\n }\n\n private __setModelValidStateTrue() {\n this.__meta.isValid = true;\n this.__setValueState(ValueState.None, ['']);\n this.__childNodes.forEach(child => {\n if (child instanceof FieldNode) {\n child.__setModelValidStateTrue();\n }\n });\n }\n\n /**\n * Updates the model from literal data, without changing the validity and value state.\n *\n * @param literal\n */\n __updateWithLiteral(literal: unknown) {\n this.__clear(true);\n // store injected literal for reset()\n this.__meta.initialValue = literal;\n // a field which is set is not empty\n this.___isEmpty = false;\n const data = structuredClone(literal);\n\n // go through available fields\n this.__meta.nodeFields.forEach(field => {\n // __clear fields which are not available in literal\n // if the field does not exist on the incoming literal, reset or __clear the value on the fieldNode\n // make an undefined on complex types\n if (\n (data as FieldNode)[field.fieldName as keyof FieldNode] === undefined\n ) {\n if (this[`_${field.fieldName}` as keyof FieldNode] !== undefined) {\n // primitives go to their default values\n (\n this[`_${field.fieldName}` as keyof FieldNode] as FieldNode\n ).__clear();\n }\n return;\n }\n\n (\n this[`_${field.fieldName}` as keyof FieldNode] as FieldNode\n ).__updateWithLiteral(\n (data as FieldNode)[field.fieldName as keyof FieldNode],\n );\n\n (\n this[`_${field.fieldName}` as keyof FieldNode] as FieldNode\n ).__meta.isPristine = false;\n });\n // set the object itself to pristine on root nodes\n\n this.__meta.isPristine = false;\n\n this.__notifyFieldValueChange(false);\n }\n\n __stringify(): string {\n return JSON.stringify(this.__toJson());\n }\n\n /**\n * Converts the model to a JSON struct wich matches the protobuf spec.\n * If the `UseProtoNames` option is set to false, lowerCamelCase is produced.\n */\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n __toJson(): any {\n const d: Record<string, unknown> = {};\n this.__meta.nodeFields.forEach(f => {\n // use jsonName if UseProtoNames is set, otherwise convert to lowerCamel without X prefix\n const jsonName = OPEN_MODELS_OPTIONS.UseProtoNames\n ? f.protoName\n : this.__toLowerCamelCaseWithoutXPrefix(f.protoName);\n\n if (OPEN_MODELS_OPTIONS.EmitUnpopulated) {\n if (\n (this[`_${f.fieldName}` as keyof FieldNode] as FieldNode).__isEmpty &&\n !(this[`_${f.fieldName}` as keyof FieldNode] as FieldNode)\n .__isPrimitive\n ) {\n d[jsonName] = null;\n } else {\n d[jsonName] = (\n this[`_${f.fieldName}` as keyof FieldNode] as FieldNode\n ).__toJson();\n }\n } else if (\n ((this as FieldNode)[`_${f.fieldName}` as keyof FieldNode] &&\n (!(this[`_${f.fieldName}` as keyof FieldNode] as FieldNode)\n .__isEmpty ||\n (this[`_${f.fieldName}` as keyof FieldNode] as FieldNode).__meta\n .required)) ||\n ((this[`_${f.fieldName}` as keyof FieldNode] as FieldNode)\n .__isPrimitive &&\n OPEN_MODELS_OPTIONS.EmitDefaultValues)\n ) {\n d[jsonName] = (\n this[`_${f.fieldName}` as keyof FieldNode] as FieldNode\n ).__toJson();\n }\n\n return null;\n });\n return d;\n }\n\n /**\n * Build up the model, using the transport Json. If UseProtoNames is set to false, lowerCamelCase is expected.\n *\n * @param {JSON} data - Transport Json\n */\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n public __fromProtoNameJson(data: any) {\n const l = this.__mapProtoNameJsonToJson(data);\n this.__fromLiteral(l);\n }\n\n /**\n * Helper function to create a literal type from a json type\n * @param {JSON} data - Transport Json\n */\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n __mapProtoNameJsonToJson(data: any): any {\n const literal: Record<string, unknown> = {};\n // map json to literal\n this.__meta.nodeFields.forEach(f => {\n const jsonName = OPEN_MODELS_OPTIONS.UseProtoNames\n ? f.protoName\n : this.__toLowerCamelCaseWithoutXPrefix(f.protoName);\n\n if (data[jsonName] !== undefined) {\n literal[f.fieldName] = (\n this[`_${f.fieldName}` as keyof FieldNode] as FieldNode\n ).__mapProtoNameJsonToJson(data[jsonName]);\n }\n });\n return literal;\n }\n\n /**\n * Converts the model to a literal type. The literal type matches the interface from ITypeName.\n */\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n public __toLiteral(): any {\n const d: Record<string, unknown> = {};\n this.__meta.nodeFields.forEach(f => {\n if (\n this[`_${f.fieldName}` as keyof FieldNode] &&\n (!(this[`_${f.fieldName}` as keyof FieldNode] as FieldNode).__isEmpty ||\n (this[`_${f.fieldName}` as keyof FieldNode] as FieldNode).__meta\n .required)\n ) {\n d[f.fieldName] = (\n this[`_${f.fieldName}` as keyof FieldNode] as FieldNode\n ).__toLiteral();\n }\n return null;\n });\n return d;\n }\n\n get __fieldPath(): string {\n const parts: string[] = [];\n this.___pathBuilder(parts);\n return parts.join('.').replaceAll('.[', '['); // replace for array paths\n }\n\n ___pathBuilder(parts: string[]): string[] {\n // the root node does not have a fieldName\n if (this.__meta.fieldName !== undefined) {\n parts.unshift(\n OPEN_MODELS_OPTIONS.UseProtoNames\n ? this.__toSnakeCase(this.__meta.fieldName)\n : this.__meta.fieldName,\n );\n this.__parentNode?.___pathBuilder(parts);\n }\n return parts;\n }\n\n /**\n * Returns the formated label using the `OPEN_MODELS_OPTIONS.labelFormatter`\n */\n get __label(): string {\n return OPEN_MODELS_OPTIONS.labelFormatter(`${this.__getBaseName()}.label`);\n }\n\n /**\n * Returns the raw label without any translations, formatters applied.\n *\n *\n */\n get __labelRaw(): string {\n return this.__getBaseName();\n }\n\n /**\n * Returns the placeholder label using the `OPEN_MODELS_OPTIONS.labelFormatter`\n */\n get __placeholder(): string {\n return OPEN_MODELS_OPTIONS.labelFormatter(\n `${this.__getBaseName()}.placeholder`,\n );\n }\n\n /**\n * Returns the formated aria description using the `OPEN_MODELS_OPTIONS.labelFormatter`\n */\n get __ariaDescription(): string {\n return OPEN_MODELS_OPTIONS.labelFormatter(\n `${this.__getBaseName()}.description`,\n );\n }\n\n /**\n * Returns a list of all states of a node and its children.\n *\n * ```json\n * [\n * {\n * \"field\": \"id\",\n * \"state\": \"Error\",\n * \"message\": \"This field is invalid\"\n * },\n * {\n * \"field\": \"display_name\",\n * \"state\": \"Error\",\n * \"message\": \"This field is invalid\"\n * }\n * ]\n * ```\n */\n public __getAllStates(): ValueStateSummary[] {\n return this.___getAllStates([]);\n }\n\n private ___getAllStates(carrier: ValueStateSummary[]): ValueStateSummary[] {\n if (this.__meta.valueState !== ValueState.None) {\n carrier.push({\n field: this.__fieldPath,\n state: this.__meta.valueState,\n message: this.__meta.stateMessage,\n });\n }\n this.__childNodes.forEach(child => {\n if (child instanceof FieldNode) {\n child.___getAllStates(carrier);\n }\n });\n return carrier;\n }\n\n /**\n * Clears all value states recursively\n */\n public __clearAllValueStates() {\n this.__meta.valueState = ValueState.None;\n this.__meta.stateMessage = '';\n this.__childNodes.forEach(child => {\n if (child instanceof FieldNode) {\n child.__clearAllValueStates();\n }\n });\n\n this.__dispatchEvent(\n new CustomEvent('state-changed', {\n detail: this,\n bubbles: false,\n }),\n );\n }\n\n /**\n * Applies a list of states to a node and its children.\n *\n * Keep in mind, that the message must be already translated.\n *\n * ```json\n * {\n * \"field\": \"id\",\n * \"state\": \"Error\",\n * \"message\": \"This field is invalid\"\n *}\n *\n * ```\n *\n */\n public __applyValueStates(...states: ValueStateSummary[]) {\n states.forEach(state => {\n const fn = this.__getFieldNodeByPath(state.field);\n if (fn !== undefined) {\n const validStateBefore = fn.__meta.isValid;\n fn.__meta.valueState = state.state;\n fn.__meta.stateMessage = state.message;\n fn.__meta.isValid = state.state !== ValueState.Negative;\n fn.__meta.businessVaueState = state.state;\n if (fn.__meta.isValid !== validStateBefore) {\n fn.__dispatchEvent(\n new CustomEvent('validity-changed', {\n detail: fn,\n bubbles: true,\n }),\n );\n }\n\n fn.__dispatchEvent(\n new CustomEvent('state-changed', {\n detail: fn,\n bubbles: false,\n }),\n );\n }\n });\n }\n\n /**\n * Returns the valid state of a node.\n * - A node is valid when all children are valid.\n * - A node is valid when freshly initialized, even when some children have invalid values.\n *\n * use `validate()` to be sure to have the correct validity state.\n *\n * Use __meta.StateMessage to receive the state of a node. The `__meta.StateMessage` is only available on an explicit field, where the validity state is populated upwards.\n */\n public get __isValid(): boolean {\n return this.__meta.isValid;\n }\n\n /**\n * set the validity of the node. This will trigger no events, just set the __meta.isValid value.\n *\n * Use this in your customValidators.\n * @param valid\n */\n public __setValidState(valid: boolean): void {\n this.__meta.isValid = valid;\n }\n\n /**\n * Initialized fields are pristine as long nothing changes inside the model.\n *\n * Use this on rootNodes only.\n */\n public get __isPristine(): boolean {\n return this.__meta.isPristine;\n }\n\n /**\n * The toString() method of Object instances returns a string representing this object. This method is meant to be overridden by `CustomPrototypes.ToString`.\n * If no `CustomPrototypes` is set, it will try to find a display_name attribute on the node and uses that for the output.\n *\n * If there is no display_name `[object TypeName]` is returned.\n */\n public toString(): string {\n const ts = ToString.get(this.__meta.typeName || '');\n if (ts) {\n return ts(this);\n }\n const found = this.__meta.nodeFields.find(\n fieldDescriptor => fieldDescriptor.fieldName === 'displayName',\n );\n if (\n found &&\n (this['displayName' as keyof FieldNode] as FieldNode).__meta.typeName ===\n 'primitives.STRING'\n ) {\n return (this['displayName' as keyof FieldNode] as FieldNode).toString();\n }\n return `[object ${this.__meta.typeName}]`;\n }\n\n /**\n * The valueOf() method of Object instances converts the this.value to an object.\n * This method is meant to be overridden by derived objects for custom type conversion logic.\n */\n public valueOf(): number | bigint {\n const ts = ValueOf.get(this.__meta.typeName || '');\n if (ts) {\n return ts(this);\n }\n return NaN;\n }\n\n /**\n * Helper method to build up labels, placeholders,...\n * @protected\n */\n protected __getBaseName(): string {\n const parts: string[] = [];\n this.___fieldNameBuilder(parts);\n return parts.join('.');\n }\n\n /**\n * Helper method to construct the __fieldPath\n * @param parts\n * @protected\n */\n protected ___fieldNameBuilder(parts: string[]): string[] {\n // stop if parent node has same typeName, we are on a recursion.\n if (this.__meta.isRecursionNode || this.__meta.isAnyNode) {\n parts.unshift(this.__meta.typeName as string);\n } else {\n // do not add the index to the baseName on Array fields\n if (!this.__meta.isArrayNode) {\n // the root node does not have a fieldName, so we use the typeName\n parts.unshift(\n // eslint-disable-next-line no-nested-ternary\n this.__meta.fieldName\n ? OPEN_MODELS_OPTIONS.UseProtoNames\n ? this.__toSnakeCase(this.__meta.fieldName)\n : this.__meta.fieldName\n : this.__meta.typeName || '',\n );\n }\n this.__parentNode?.___fieldNameBuilder(parts);\n }\n return parts;\n }\n\n /**\n * Validate the node and all child nodes of it.\n */\n public __validate() {\n const validStateBefore = this.__meta.isValid;\n // trigger the local listeners\n this.__validationExecuter(this);\n\n let allChildrenValid = true;\n // do not go deeper if node is invalid, because business validators can set sub fields\n\n // dispatch to children\n this.__childNodes.forEach(child => {\n if (child instanceof FieldNode) {\n if (child.__meta.businessVaueState === ValueState.None) {\n // this only check constraints, but business errors are higher order\n child.__validate();\n }\n\n if (!child.__isValid) {\n allChildrenValid = false;\n }\n }\n });\n\n this.__meta.isValid = allChildrenValid && this.__isValid;\n if (this.__meta.isValid !== validStateBefore) {\n this.__dispatchEvent(\n new CustomEvent('validity-changed', {\n detail: this,\n bubbles: false,\n }),\n );\n }\n }\n\n /**\n * Validates all parents of an element. This is done when you set a value on any child/attribute of a node directly\n * @param {FieldNode} node - Any FieldNode\n */\n protected __validateBottomUp(node: FieldNode) {\n // \"this\" is usually the parent node of \"node\"\n this.__validationExecuter(node);\n // climb up and check children state to define the own state of \"this\"\n node.__climbUpValidation();\n }\n\n /**\n * Validates all parent nodes if a sub-field was changed.\n * @protected\n */\n protected __climbUpValidation() {\n const validStateBefore = this.__meta.isValid;\n this.__validationExecuter(this);\n\n let allChildrenValid = true;\n this.__childNodes.forEach(child => {\n if (child instanceof FieldNode) {\n if (!child.__isValid) {\n allChildrenValid = false;\n }\n }\n });\n // if any child is not valid, this is also not valid\n this.__meta.isValid = allChildrenValid && this.__isValid;\n if (this.__meta.isValid !== validStateBefore) {\n this.__dispatchEvent(\n new CustomEvent('validity-changed', {\n detail: this,\n bubbles: false,\n }),\n );\n }\n\n if (this.__parentNode) {\n this.__parentNode.__climbUpValidation();\n }\n }\n\n /**\n * Additional \"constraint\" checker for primitive types, i.e. INT32 can only range from -2147483648 to 2147483647, but js uses always a float64 to handle numbers\n * @protected\n */\n // eslint-disable-next-line class-methods-use-this\n protected __checkTypeBoundaries(): string[] | undefined {\n return undefined;\n }\n\n /**\n * Executes the validation process.\n * @param node\n * @protected\n */\n // eslint-disable-next-line class-methods-use-this\n protected __validationExecuter(node: FieldNode) {\n const validatorFunc = Validators.get(node.__meta.typeName);\n const customConstraintsFunc = CustomConstraints.get(node.__meta.typeName);\n const fieldConstraints = node.__getConstraints();\n let constraintMessage: undefined | string[];\n\n constraintMessage = this.__checkTypeBoundaries();\n\n if (\n validatorFunc ||\n fieldConstraints ||\n customConstraintsFunc ||\n constraintMessage\n ) {\n if (fieldConstraints && !customConstraintsFunc) {\n constraintMessage = node.__checkConstraints(fieldConstraints);\n }\n if (customConstraintsFunc) {\n constraintMessage = customConstraintsFunc(node);\n }\n if (validatorFunc) {\n validatorFunc(node);\n } else if (constraintMessage === undefined) {\n node.__setValueState(ValueState.None, ['']);\n }\n if (constraintMessage !== undefined) {\n node.__setValueState(ValueState.Negative, constraintMessage);\n }\n } else {\n node.__setValueState(ValueState.None, ['']);\n }\n }\n\n /**\n * Receives all constraints of a node. Use this in your custom validators or components.\n */\n public __getConstraints(): FieldConstraints | undefined {\n if (this.__meta.isArrayNode && this.__parentNode?.__parentNode) {\n const fieldDescriptor =\n this.__parentNode.__parentNode.__meta.nodeFields.find(\n f => f.fieldName === this.__parentNode!.__meta.fieldName,\n );\n return fieldDescriptor?.constraints;\n }\n\n if (this.__parentNode) {\n const fieldDescriptor = this.__parentNode.__meta.nodeFields.find(\n f => f.fieldName === this.__meta.fieldName,\n );\n return fieldDescriptor?.constraints;\n }\n return undefined;\n }\n\n /**\n * Set the value state\n * @param {ValueState} state - The state of the node.\n * @param {string[]} messageAndParams - Description for the formatter.\n */\n __setValueState(state: ValueState, messageAndParams: string[]) {\n const shouldNotify = this.__meta.valueState !== state;\n this.__meta.valueState = state;\n this.__meta.stateMessage = OPEN_MODELS_OPTIONS.valueStateMessageFormatter(\n messageAndParams[0],\n ...messageAndParams.slice(1),\n );\n // set invalid on error state\n // the event is sent from ...\n this.__meta.isValid = state !== ValueState.Negative;\n\n if (shouldNotify) {\n this.__dispatchEvent(\n new CustomEvent('state-changed', {\n detail: this,\n bubbles: false,\n }),\n );\n }\n }\n\n /**\n * Resets the node to the last inserted literal or to the initial state.\n * // todo: reset to default values not just the empty state\n */\n public __reset() {\n if (this.__meta.initialValue !== undefined) {\n this.__updateWithLiteral(this.__meta.initialValue);\n this.__meta.isPristine = true;\n return;\n }\n // else re init every field downwards\n this.__clear();\n this.__meta.isPristine = true;\n }\n\n /**\n * Clear clears the element downwards and set __isEmpty to true on all sub nodes.\n *\n * A cleared field is not populated on `__toLiteral` or `__toJson` when the option `EmitUnpopulated` or `EmitDefaultValues` is set to false.\n */\n public __clear(withoutNotification: boolean = false) {\n this.__isEmpty = true;\n\n // __clear every childNode too\n this.__meta.nodeFields.forEach(descriptor => {\n (\n this[`_${descriptor.fieldName}` as keyof FieldNode] as FieldNode\n ).__clear(withoutNotification);\n });\n if (!withoutNotification) {\n this.__notifyFieldValueChange(false);\n }\n // todo: set to values to default value or initial\n // todo: set state to None\n // todo: set valid to true\n }\n\n /**\n * Helper method to update a skalar / primitive field of a type. Used by the generated models.\n * Triggers also the validation and clearance, if needed.\n *\n * @param {FieldNode} targetNode - The field of a FieldNode\n * @param {string | boolean | number} value - The value you want to set\n * @protected\n */\n // eslint-disable-next-line class-methods-use-this\n protected __PrimitivesSetter(targetNode: IPrimitive, value: unknown) {\n // do not do anything if current value equals val\n if (targetNode._value !== value) {\n targetNode._value = value; // eslint-disable-line no-param-reassign\n\n targetNode.__isEmpty = false; // eslint-disable-line no-param-reassign\n this.__validateBottomUp(targetNode);\n targetNode.__notifyFieldValueChange(true);\n }\n }\n\n /**\n * Helper method to update a field of a type. Used by the generated models.\n * Triggers also the validation and clearance, if needed.\n *\n * @param {FieldNode} targetNode - The field of a FieldNode\n * @param {} literalData - The literal type matches the interface from ITypeName.\n * @protected\n */\n // eslint-disable-next-line class-methods-use-this\n protected __TypeSetter(\n targetNode: FieldNode,\n literalData: unknown | undefined | null,\n ) {\n if (literalData === undefined || literalData === null) {\n targetNode.__clear();\n this.__validateBottomUp(targetNode);\n targetNode.__notifyFieldValueChange(true);\n return;\n }\n\n targetNode.__updateWithLiteral(literalData); // keep the references by getting the values\n // this is the parent of the target_node\n targetNode.___updateNotEmptyPath();\n this.__validateBottomUp(targetNode);\n targetNode.__notifyFieldValueChange(true);\n }\n\n /**\n * Notifies field changes\n * @param bubbles\n * @protected\n */\n protected __notifyFieldValueChange(bubbles?: boolean) {\n this.__dispatchEvent(\n new CustomEvent('this-field-value-changed', {\n detail: this,\n bubbles: false,\n }),\n );\n\n if (bubbles) {\n this.__rootNode.__meta.isPristine = false;\n // todo check if nodes in between this and root should be set to false too\n // check ARRAY.ts line 120 too\n this.__meta.isPristine = false;\n\n // console.log('bubble', this.__meta.typeName)\n this.__dispatchEvent(\n new CustomEvent('field-value-changed', {\n detail: this,\n bubbles: true,\n }),\n );\n this.__dispatchEvent(\n new CustomEvent('update', {\n detail: this,\n bubbles: true,\n }),\n );\n } else {\n // triggered on clear or fromLiteral\n this.__dispatchEvent(\n new CustomEvent('field-value-updated', {\n detail: this,\n bubbles: false,\n }),\n );\n\n this.__dispatchEvent(\n new CustomEvent('update', {\n detail: this,\n bubbles: false,\n }),\n );\n }\n }\n\n /**\n * Returns the child nodes of a node.\n */\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n public get __childNodes(): any[] {\n return this.__meta.nodeFields.map(\n field => this[field.fieldName as keyof FieldNode],\n );\n }\n\n /**\n * Broadcast an event to all child nodes of a field node.\n * @param event\n */\n __broadcastEvent(event: CustomEvent) {\n // trigger the local listeners\n this.__triggerNodeEvents(event);\n\n // dispatch to children\n this.__childNodes.forEach(child => {\n if (child instanceof FieldNode) {\n child.__broadcastEvent(event);\n }\n });\n }\n\n /**\n * Dispatches a custom event on a FieldNode\n * @param {CustomEvent} event - A generic custom event.\n */\n __dispatchEvent(event: CustomEvent): CustomEvent {\n // trigger the events on current node\n this.__triggerNodeEvents(event);\n\n // go to parent\n if (event.bubbles && this.__parentNode !== undefined) {\n return this.__parentNode.__dispatchEvent(event);\n }\n return event;\n }\n\n /**\n * Helper method to invoke/execute the event on the current node\n * @param event\n * @protected\n */\n protected __triggerNodeEvents(event: CustomEvent<FieldNode>) {\n if (\n this.__meta.eventListener.has(event.type) &&\n this.__meta.eventListener.get(event.type)!.length > 0\n ) {\n this.__meta.eventListener\n .get(event.type)!\n .forEach((t, i, listenerArray) => {\n t.callbackfn(event);\n if (\n t.options !== undefined &&\n typeof t.options !== 'boolean' &&\n t.options.once\n ) {\n // eslint-disable-next-line no-param-reassign\n delete listenerArray[i];\n }\n });\n }\n }\n\n /**\n * Add a handler to a node\n * @param {string} type - A case-sensitive string representing the event type to listen for.\n * @param {function} listener - The object that receives a notification (an object that implements the Event interface) when an event of the specified type occurs. This must be null, an object with a handleEvent() method, or a JavaScript function. See The event listener callback for details on the callback itself.\n * @param {} options - An object that specifies characteristics about the event listener. \\n\\nThe available option is `once:boolean`\n */\n public __addEventListener(\n type: EventType,\n listener: CustomEventListener,\n options?: boolean | AddEventListenerOptions,\n ): void {\n if (!this.__meta.eventListener.has(type)) {\n this.__meta.eventListener.set(type, []);\n }\n this.__meta.eventListener\n .get(type)!\n .push({ callbackfn: listener, options });\n }\n\n // add a listener for a custom event, defined and triggered by yourself\n // this could be something like 'focus-requested'\n public __addCustomEventListener(\n type: string,\n handler: CustomEventListener,\n options?: boolean | AddEventListenerOptions,\n ): void {\n if (!this.__meta.eventListener.has(type)) {\n this.__meta.eventListener.set(type, []);\n }\n this.__meta.eventListener.get(type)!.push({ callbackfn: handler, options });\n }\n\n /**\n * Removes the handler from a node\n * @param type\n * @param handler\n * @param options\n */\n public __removeEventListener(\n type: EventType,\n handler: CustomEventListener,\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n options?: boolean | EventListenerOptions,\n ): void {\n if (this.__meta.eventListener.has(type)) {\n this.__meta.eventListener.set(\n type,\n this.__meta.eventListener\n .get(type)!\n .filter(e => e.callbackfn !== handler),\n );\n }\n }\n\n /**\n * Removes the handler from a node\n * @param type\n * @param handler\n * @param options\n */\n public __removeCustomEventListener(\n type: string,\n handler: CustomEventListener,\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n options?: boolean | EventListenerOptions,\n ): void {\n if (this.__meta.eventListener.has(type)) {\n this.__meta.eventListener.set(\n type,\n this.__meta.eventListener\n .get(type)!\n .filter(e => e.callbackfn !== handler),\n );\n }\n }\n\n /**\n * if some child is not empty, set isEmpty to false, all the way up to the root node\n * @private\n */\n protected ___updateNotEmptyPath() {\n this.___isEmpty = false;\n if (this.__parentNode !== undefined && this.__parentNode.__isEmpty) {\n this.__parentNode.___updateNotEmptyPath();\n }\n }\n\n // eslint-disable-next-line class-methods-use-this\n protected __checkConstraints(\n fieldConstraints: FieldConstraints,\n ): string[] | undefined {\n if (fieldConstraints.required) {\n if (this.__isEmpty) {\n return ['constraint.violation.required'];\n }\n }\n return undefined;\n }\n\n // eslint-disable-next-line class-methods-use-this\n private __toLowerCamelCase(string: string) {\n if (OPEN_MODELS_OPTIONS.UseProtoNames) {\n const [start, ...rest] = (\n string[0] === '_' ? string.replace('_', 'X') : string\n ).split('_');\n return (\n start +\n rest\n .map(s => {\n if (s.length === 0) return '';\n return s[0].toUpperCase() + s.slice(1);\n })\n .join('')\n );\n }\n return string;\n }\n\n // eslint-disable-next-line class-methods-use-this\n protected __toLowerCamelCaseWithoutXPrefix(string: string) {\n if (OPEN_MODELS_OPTIONS.UseProtoNames) {\n const [start, ...rest] = (\n string[0] === '_' ? string.replace('_', 'X') : string\n ).split('_');\n return (\n start +\n rest\n .map(s => {\n if (s.length === 0) return '';\n return s[0].toUpperCase() + s.slice(1);\n })\n .join('')\n );\n }\n return string;\n }\n\n // eslint-disable-next-line class-methods-use-this\n private __toSnakeCase(string: string): string {\n return string\n .split(/(?=[A-Z])/)\n .map(word => word.toLowerCase())\n .join('_');\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"FieldNode.js","sourceRoot":"","sources":["../src/FieldNode.ts"],"names":[],"mappings":"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","sourcesContent":["/* eslint-disable max-classes-per-file, no-use-before-define */\n\n/**\n * notes: i18n is not part of the api anymore\n */\nimport { ValueState } from './ValueState';\nimport { ToString, ValueOf } from './CustomPrototypes';\nimport { CustomConstraints, Validators } from './Validator';\nimport { OPEN_MODELS_OPTIONS } from './OPEN_MODELS_OPTIONS';\nimport { FieldConstraints } from './FieldConstraints';\n\nexport type ModelEventType =\n | 'update' // triggered on any change,update,array changes, map changes, reset, model injections, from literal. Listen to this if you do not need specialized update notifications.\n | 'field-value-changed' // triggered on change or value assignment\n | 'this-field-value-changed' // triggered on every direct change on the field, not from children\n | 'field-value-updated' // triggered on clear or fromLiteral => model-injected\n | 'this-state-changed' // triggered when value states are changed\n | 'state-changed' // triggered when value states are changed\n | 'validity-changed'\n | 'array-changed'\n | 'this-array-changed'\n | 'map-changed'\n | 'this-map-changed'\n | 'parent-readonly-set' // fired when a parent was set to *ro*, listen to this event to make your UI element readonly.\n | 'parent-readonly-unset' // fired when a parent was set to *rw*, listen to this event to make your UI element writable, but you have to check for your own *ro state* and any *ro* parent.\n // | 'child-readonly-set' implement this when @maltenorstroem asks for it\n // | 'child-readonly-unset' implement this when @maltenorstroem asks for it\n | 'model-injected'; // fired on the injection node before field-value-updated and this-field-value-changed\n\ntype Meta = {\n businessVaueState: ValueState;\n index?: number;\n oldValue?: unknown;\n initialValue: unknown; // Initial value from __updateWithLiteral\n typeName: string; // i.e \"furo.fat.Bool\"\n fieldName?: string; // field name of this node used by its parent node\n valueState: ValueState;\n stateMessage: string;\n nodeFields: FieldDescriptor[];\n readonly: boolean;\n required: boolean;\n isArrayNode: boolean; // set by array and used by baseName resolver to omit the index in the names\n deleteArrayNode?: () => void; // only available on array nodes\n isRecursionNode: boolean;\n isAnyNode: boolean;\n isValid: boolean;\n isPristine: boolean;\n eventListener: Map<\n string,\n {\n callbackfn: CustomEventListener;\n options?: AddEventListenerOptions | boolean;\n }[]\n >;\n // Description of the message type itself. Used for AI jsonschema generation.\n description?: string;\n};\n\n/**\n * Primitives have always a value field\n */\ninterface IPrimitive extends FieldNode {\n _value: unknown; // contains the value of the FieldNode\n}\n\ninterface CustomEventListener {\n (evt: CustomEvent): void;\n}\n\nexport type FieldDescriptor = {\n // camel case name of the field\n fieldName: string;\n // API name of the field, defined by contract.\n protoName: string;\n // class of the type, must start with cap\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n FieldConstructor: any; // (new(_initData: any, parent?: FieldNode, parentAttributeName?: string) => FieldNode);\n ValueConstructor?: new () => FieldNode; // used by MAP\n constraints?: FieldConstraints;\n // Optional description to generate AI friendly jsonschema\n description?: string;\n};\n\nexport interface ValueStateSummary {\n /**\n * path of the field\n *\n * `fullName` for a violation in the `fullName` value\n * `emailAddresses[1].email` for a violation in the `email` field of the first `emailAddresses` message\n * `emailAddresses[3].type[2]` for a violation in the second `type` value in the third `emailAddresses` message.\n */\n field: string;\n state: ValueState;\n message: string;\n}\n\nexport abstract class FieldNode {\n protected ___isEmpty: boolean = true;\n\n /**\n * Marker for primitive types\n */\n public __isPrimitive: boolean = false;\n\n /**\n * Parent node of a node. This is undefined on root nodes.\n */\n public __parentNode: FieldNode | undefined;\n\n /**\n * Metadata of a field node.\n */\n public __meta: Meta = {\n businessVaueState: ValueState.None,\n readonly: false,\n required: false,\n initialValue: undefined,\n isPristine: true,\n isValid: true,\n valueState: ValueState.None,\n stateMessage: '',\n typeName: '',\n nodeFields: [],\n isArrayNode: false,\n isRecursionNode: false,\n isAnyNode: false,\n eventListener: new Map<string, []>(),\n };\n\n private ___rootNode: FieldNode;\n\n private ___readonlyState: Map<FieldNode, boolean> = new Map<\n FieldNode,\n boolean\n >();\n\n /**\n * Root node of a node\n */\n get __rootNode(): FieldNode {\n return this.___rootNode;\n }\n\n /**\n * Root node of a node. Do not set this value by yourself.\n * @param value\n */\n set __rootNode(value: FieldNode) {\n this.___rootNode = value;\n }\n\n /**\n * Empty state of the node\n */\n get __isEmpty() {\n return this.___isEmpty;\n }\n\n /**\n * Empty state of the node\n * @param empty\n */\n set __isEmpty(empty: boolean) {\n if (empty) {\n this.___isEmpty = true;\n } else {\n this.___updateNotEmptyPath();\n }\n }\n\n constructor(\n _initData: undefined,\n parent?: FieldNode,\n parentAttributeName?: string,\n ) {\n this.__parentNode = parent;\n\n if (parent) {\n this.___rootNode = parent.__rootNode;\n } else {\n this.___rootNode = this;\n }\n\n this.__meta.fieldName = parentAttributeName;\n }\n\n /**\n * Get a FieldNode by giving a field path using the proto names for the fields.\n *\n *\n *\n * - `email_addresses[3].type[2]` for the second `type` value in the third `email_addresses` message.\n * - `user.location.street` for the street in location in user.\n *\n * @param {string} deepPath - Path of the field.\n */\n __getFieldNodeByPath(deepPath: string = ''): FieldNode | undefined {\n // replace array paths\n const path = deepPath.replaceAll(/[[\\]]/g, '.').split('.');\n if (path.length > 0 && path[0] !== '') {\n // rest wieder in error reinwerfen\n // eslint-disable-next-line no-param-reassign\n deepPath = path.slice(1).join('.');\n // convert to camel\n const fieldName = this.__toLowerCamelCase(path[0]) as keyof FieldNode;\n\n if (deepPath === '') {\n if (this[fieldName]) {\n return this[fieldName] as FieldNode;\n }\n } else if (this[fieldName]) {\n return (this[fieldName] as FieldNode).__getFieldNodeByPath(deepPath);\n }\n return undefined;\n }\n return undefined;\n }\n\n /**\n * Check if the node is \"readonly\"\n *\n * When any this node or any parent is *ro*, this will return false.\n *\n */\n public __isLogicalReadonly(): boolean {\n if (this.__readonly) {\n return true;\n }\n if (this.__parentNode) {\n return this.__parentNode.__isLogicalReadonly();\n }\n return false;\n }\n\n /**\n * Set the readonly state\n * @param v\n */\n public set __readonly(v: boolean) {\n // to save resources, we could check for __isReadonly and fire the event based on this\n this.__meta.readonly = v;\n // dispatch to children\n this.__broadcastEvent(\n new CustomEvent(v ? 'parent-readonly-set' : 'parent-readonly-unset', {\n detail: this,\n bubbles: false,\n }),\n );\n }\n\n get __readonly(): boolean {\n return this.__meta.readonly;\n }\n\n /**\n * Build up the model with the literal type. The literal type matches the interface from ITypeName.\n * @param {} literal - The literal type matches the interface from ITypeName.\n */\n __fromLiteral(literal: unknown) {\n this.__updateWithLiteral(literal);\n // clear the state of the validity and value state\n this.__setModelValidStateTrue();\n\n this.__dispatchEvent(\n new CustomEvent('model-injected', {\n composed: true,\n bubbles: false,\n detail: this,\n }),\n );\n\n this.__meta.isPristine = true;\n // this.__notifyFieldValueChange(true);\n }\n\n private __setModelValidStateTrue() {\n this.__meta.isValid = true;\n this.__setValueState(ValueState.None, ['']);\n this.__childNodes.forEach(child => {\n if (child instanceof FieldNode) {\n child.__setModelValidStateTrue();\n }\n });\n }\n\n /**\n * Updates the model from literal data, without changing the validity and value state.\n *\n * @param literal\n */\n __updateWithLiteral(literal: unknown) {\n this.__clear(true);\n // store injected literal for reset()\n this.__meta.initialValue = literal;\n // a field which is set is not empty\n this.___isEmpty = false;\n const data = structuredClone(literal);\n\n // go through available fields\n this.__meta.nodeFields.forEach(field => {\n // __clear fields which are not available in literal\n // if the field does not exist on the incoming literal, reset or __clear the value on the fieldNode\n // make an undefined on complex types\n if (\n (data as FieldNode)[field.fieldName as keyof FieldNode] === undefined\n ) {\n if (this[`_${field.fieldName}` as keyof FieldNode] !== undefined) {\n // primitives go to their default values\n (\n this[`_${field.fieldName}` as keyof FieldNode] as FieldNode\n ).__clear();\n }\n return;\n }\n\n (\n this[`_${field.fieldName}` as keyof FieldNode] as FieldNode\n ).__updateWithLiteral(\n (data as FieldNode)[field.fieldName as keyof FieldNode],\n );\n\n (\n this[`_${field.fieldName}` as keyof FieldNode] as FieldNode\n ).__meta.isPristine = false;\n });\n // set the object itself to pristine on root nodes\n\n this.__meta.isPristine = false;\n\n this.__notifyFieldValueChange(false);\n }\n\n __stringify(): string {\n return JSON.stringify(this.__toJson());\n }\n\n /**\n * Converts the model to a JSON struct wich matches the protobuf spec.\n * If the `UseProtoNames` option is set to false, lowerCamelCase is produced.\n */\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n __toJson(): any {\n const d: Record<string, unknown> = {};\n this.__meta.nodeFields.forEach(f => {\n // use jsonName if UseProtoNames is set, otherwise convert to lowerCamel without X prefix\n const jsonName = OPEN_MODELS_OPTIONS.UseProtoNames\n ? f.protoName\n : this.__toLowerCamelCaseWithoutXPrefix(f.protoName);\n\n if (OPEN_MODELS_OPTIONS.EmitUnpopulated) {\n if (\n (this[`_${f.fieldName}` as keyof FieldNode] as FieldNode).__isEmpty &&\n !(this[`_${f.fieldName}` as keyof FieldNode] as FieldNode)\n .__isPrimitive\n ) {\n d[jsonName] = null;\n } else {\n d[jsonName] = (\n this[`_${f.fieldName}` as keyof FieldNode] as FieldNode\n ).__toJson();\n }\n } else if (\n ((this as FieldNode)[`_${f.fieldName}` as keyof FieldNode] &&\n (!(this[`_${f.fieldName}` as keyof FieldNode] as FieldNode)\n .__isEmpty ||\n (this[`_${f.fieldName}` as keyof FieldNode] as FieldNode).__meta\n .required)) ||\n ((this[`_${f.fieldName}` as keyof FieldNode] as FieldNode)\n .__isPrimitive &&\n OPEN_MODELS_OPTIONS.EmitDefaultValues)\n ) {\n d[jsonName] = (\n this[`_${f.fieldName}` as keyof FieldNode] as FieldNode\n ).__toJson();\n }\n\n return null;\n });\n return d;\n }\n\n /**\n * Build up the model, using the transport Json. If UseProtoNames is set to false, lowerCamelCase is expected.\n *\n * @param {JSON} data - Transport Json\n */\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n public __fromProtoNameJson(data: any) {\n const l = this.__mapProtoNameJsonToJson(data);\n this.__fromLiteral(l);\n }\n\n /**\n * Helper function to create a literal type from a json type\n * @param {JSON} data - Transport Json\n */\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n __mapProtoNameJsonToJson(data: any): any {\n const literal: Record<string, unknown> = {};\n // map json to literal\n this.__meta.nodeFields.forEach(f => {\n const jsonName = OPEN_MODELS_OPTIONS.UseProtoNames\n ? f.protoName\n : this.__toLowerCamelCaseWithoutXPrefix(f.protoName);\n\n if (data[jsonName] !== undefined) {\n literal[f.fieldName] = (\n this[`_${f.fieldName}` as keyof FieldNode] as FieldNode\n ).__mapProtoNameJsonToJson(data[jsonName]);\n }\n });\n return literal;\n }\n\n /**\n * Converts the model to a literal type. The literal type matches the interface from ITypeName.\n */\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n public __toLiteral(): any {\n const d: Record<string, unknown> = {};\n this.__meta.nodeFields.forEach(f => {\n if (\n this[`_${f.fieldName}` as keyof FieldNode] &&\n (!(this[`_${f.fieldName}` as keyof FieldNode] as FieldNode).__isEmpty ||\n (this[`_${f.fieldName}` as keyof FieldNode] as FieldNode).__meta\n .required)\n ) {\n d[f.fieldName] = (\n this[`_${f.fieldName}` as keyof FieldNode] as FieldNode\n ).__toLiteral();\n }\n return null;\n });\n return d;\n }\n\n get __fieldPath(): string {\n const parts: string[] = [];\n this.___pathBuilder(parts);\n return parts.join('.').replaceAll('.[', '['); // replace for array paths\n }\n\n ___pathBuilder(parts: string[]): string[] {\n // the root node does not have a fieldName\n if (this.__meta.fieldName !== undefined) {\n parts.unshift(\n OPEN_MODELS_OPTIONS.UseProtoNames\n ? this.__toSnakeCase(this.__meta.fieldName)\n : this.__meta.fieldName,\n );\n this.__parentNode?.___pathBuilder(parts);\n }\n return parts;\n }\n\n /**\n * Returns the formated label using the `OPEN_MODELS_OPTIONS.labelFormatter`\n */\n get __label(): string {\n return OPEN_MODELS_OPTIONS.labelFormatter(`${this.__getBaseName()}.label`);\n }\n\n /**\n * Returns the raw label without any translations, formatters applied.\n *\n *\n */\n get __labelRaw(): string {\n return this.__getBaseName();\n }\n\n /**\n * Returns the placeholder label using the `OPEN_MODELS_OPTIONS.labelFormatter`\n */\n get __placeholder(): string {\n return OPEN_MODELS_OPTIONS.labelFormatter(\n `${this.__getBaseName()}.placeholder`,\n );\n }\n\n /**\n * Returns the formated aria description using the `OPEN_MODELS_OPTIONS.labelFormatter`\n */\n get __ariaDescription(): string {\n return OPEN_MODELS_OPTIONS.labelFormatter(\n `${this.__getBaseName()}.description`,\n );\n }\n\n /**\n * Returns a list of all states of a node and its children.\n *\n * ```json\n * [\n * {\n * \"field\": \"id\",\n * \"state\": \"Error\",\n * \"message\": \"This field is invalid\"\n * },\n * {\n * \"field\": \"display_name\",\n * \"state\": \"Error\",\n * \"message\": \"This field is invalid\"\n * }\n * ]\n * ```\n */\n public __getAllStates(): ValueStateSummary[] {\n return this.___getAllStates([]);\n }\n\n private ___getAllStates(carrier: ValueStateSummary[]): ValueStateSummary[] {\n if (this.__meta.valueState !== ValueState.None) {\n carrier.push({\n field: this.__fieldPath,\n state: this.__meta.valueState,\n message: this.__meta.stateMessage,\n });\n }\n this.__childNodes.forEach(child => {\n if (child instanceof FieldNode) {\n child.___getAllStates(carrier);\n }\n });\n return carrier;\n }\n\n /**\n * Clears all value states recursively\n */\n public __clearAllValueStates() {\n this.__meta.valueState = ValueState.None;\n this.__meta.stateMessage = '';\n this.__childNodes.forEach(child => {\n if (child instanceof FieldNode) {\n child.__clearAllValueStates();\n }\n });\n\n this.__dispatchEvent(\n new CustomEvent('state-changed', {\n detail: this,\n bubbles: false,\n }),\n );\n }\n\n /**\n * Applies a list of states to a node and its children.\n *\n * Keep in mind, that the message must be already translated.\n *\n * ```json\n * {\n * \"field\": \"id\",\n * \"state\": \"Error\",\n * \"message\": \"This field is invalid\"\n *}\n *\n * ```\n *\n */\n public __applyValueStates(...states: ValueStateSummary[]) {\n states.forEach(state => {\n const fn = this.__getFieldNodeByPath(state.field);\n if (fn !== undefined) {\n const validStateBefore = fn.__meta.isValid;\n fn.__meta.valueState = state.state;\n fn.__meta.stateMessage = state.message;\n fn.__meta.isValid = state.state !== ValueState.Negative;\n fn.__meta.businessVaueState = state.state;\n if (fn.__meta.isValid !== validStateBefore) {\n fn.__dispatchEvent(\n new CustomEvent('validity-changed', {\n detail: fn,\n bubbles: true,\n }),\n );\n }\n\n fn.__dispatchEvent(\n new CustomEvent('state-changed', {\n detail: fn,\n bubbles: false,\n }),\n );\n }\n });\n }\n\n /**\n * Returns the valid state of a node.\n * - A node is valid when all children are valid.\n * - A node is valid when freshly initialized, even when some children have invalid values.\n *\n * use `validate()` to be sure to have the correct validity state.\n *\n * Use __meta.StateMessage to receive the state of a node. The `__meta.StateMessage` is only available on an explicit field, where the validity state is populated upwards.\n */\n public get __isValid(): boolean {\n return this.__meta.isValid;\n }\n\n /**\n * set the validity of the node. This will trigger no events, just set the __meta.isValid value.\n *\n * Use this in your customValidators.\n * @param valid\n */\n public __setValidState(valid: boolean): void {\n this.__meta.isValid = valid;\n }\n\n /**\n * Initialized fields are pristine as long nothing changes inside the model.\n *\n * Use this on rootNodes only.\n */\n public get __isPristine(): boolean {\n return this.__meta.isPristine;\n }\n\n /**\n * The toString() method of Object instances returns a string representing this object. This method is meant to be overridden by `CustomPrototypes.ToString`.\n * If no `CustomPrototypes` is set, it will try to find a display_name attribute on the node and uses that for the output.\n *\n * If there is no display_name `[object TypeName]` is returned.\n */\n public toString(): string {\n const ts = ToString.get(this.__meta.typeName || '');\n if (ts) {\n return ts(this);\n }\n const found = this.__meta.nodeFields.find(\n fieldDescriptor => fieldDescriptor.fieldName === 'displayName',\n );\n if (\n found &&\n (this['displayName' as keyof FieldNode] as FieldNode).__meta.typeName ===\n 'primitives.STRING'\n ) {\n return (this['displayName' as keyof FieldNode] as FieldNode).toString();\n }\n return `[object ${this.__meta.typeName}]`;\n }\n\n /**\n * The valueOf() method of Object instances converts the this.value to an object.\n * This method is meant to be overridden by derived objects for custom type conversion logic.\n */\n public valueOf(): number | bigint {\n const ts = ValueOf.get(this.__meta.typeName || '');\n if (ts) {\n return ts(this);\n }\n return NaN;\n }\n\n /**\n * Helper method to build up labels, placeholders,...\n * @protected\n */\n protected __getBaseName(): string {\n const parts: string[] = [];\n this.___fieldNameBuilder(parts);\n return parts.join('.');\n }\n\n /**\n * Helper method to construct the __fieldPath\n * @param parts\n * @protected\n */\n protected ___fieldNameBuilder(parts: string[]): string[] {\n // stop if parent node has same typeName, we are on a recursion.\n if (this.__meta.isRecursionNode || this.__meta.isAnyNode) {\n parts.unshift(this.__meta.typeName as string);\n } else {\n // do not add the index to the baseName on Array fields\n if (!this.__meta.isArrayNode) {\n // the root node does not have a fieldName, so we use the typeName\n parts.unshift(\n // eslint-disable-next-line no-nested-ternary\n this.__meta.fieldName\n ? OPEN_MODELS_OPTIONS.UseProtoNames\n ? this.__toSnakeCase(this.__meta.fieldName)\n : this.__meta.fieldName\n : this.__meta.typeName || '',\n );\n }\n this.__parentNode?.___fieldNameBuilder(parts);\n }\n return parts;\n }\n\n /**\n * Validate the node and all child nodes of it.\n */\n public __validate() {\n const validStateBefore = this.__meta.isValid;\n // trigger the local listeners\n this.__validationExecuter(this);\n\n let allChildrenValid = true;\n // do not go deeper if node is invalid, because business validators can set sub fields\n\n // dispatch to children\n this.__childNodes.forEach(child => {\n if (child instanceof FieldNode) {\n if (child.__meta.businessVaueState === ValueState.None) {\n // this only check constraints, but business errors are higher order\n child.__validate();\n }\n\n if (!child.__isValid) {\n allChildrenValid = false;\n }\n }\n });\n\n this.__meta.isValid = allChildrenValid && this.__isValid;\n if (this.__meta.isValid !== validStateBefore) {\n this.__dispatchEvent(\n new CustomEvent('validity-changed', {\n detail: this,\n bubbles: false,\n }),\n );\n }\n }\n\n /**\n * Validates all parents of an element. This is done when you set a value on any child/attribute of a node directly\n * @param {FieldNode} node - Any FieldNode\n */\n protected __validateBottomUp(node: FieldNode) {\n // \"this\" is usually the parent node of \"node\"\n this.__validationExecuter(node);\n // climb up and check children state to define the own state of \"this\"\n node.__climbUpValidation();\n }\n\n /**\n * Validates all parent nodes if a sub-field was changed.\n * @protected\n */\n protected __climbUpValidation() {\n const validStateBefore = this.__meta.isValid;\n this.__validationExecuter(this);\n\n let allChildrenValid = true;\n this.__childNodes.forEach(child => {\n if (child instanceof FieldNode) {\n if (!child.__isValid) {\n allChildrenValid = false;\n }\n }\n });\n // if any child is not valid, this is also not valid\n this.__meta.isValid = allChildrenValid && this.__isValid;\n if (this.__meta.isValid !== validStateBefore) {\n this.__dispatchEvent(\n new CustomEvent('validity-changed', {\n detail: this,\n bubbles: false,\n }),\n );\n }\n\n if (this.__parentNode) {\n this.__parentNode.__climbUpValidation();\n }\n }\n\n /**\n * Additional \"constraint\" checker for primitive types, i.e. INT32 can only range from -2147483648 to 2147483647, but js uses always a float64 to handle numbers\n * @protected\n */\n // eslint-disable-next-line class-methods-use-this\n protected __checkTypeBoundaries(): string[] | undefined {\n return undefined;\n }\n\n /**\n * Executes the validation process.\n * @param node\n * @protected\n */\n // eslint-disable-next-line class-methods-use-this\n protected __validationExecuter(node: FieldNode) {\n const validatorFunc = Validators.get(node.__meta.typeName);\n const customConstraintsFunc = CustomConstraints.get(node.__meta.typeName);\n const fieldConstraints = node.__getConstraints();\n let constraintMessage: undefined | string[];\n\n constraintMessage = this.__checkTypeBoundaries();\n\n if (\n validatorFunc ||\n fieldConstraints ||\n customConstraintsFunc ||\n constraintMessage\n ) {\n if (fieldConstraints && !customConstraintsFunc) {\n constraintMessage = node.__checkConstraints(fieldConstraints);\n }\n if (customConstraintsFunc) {\n constraintMessage = customConstraintsFunc(node);\n }\n if (validatorFunc) {\n validatorFunc(node);\n } else if (constraintMessage === undefined) {\n node.__setValueState(ValueState.None, ['']);\n }\n if (constraintMessage !== undefined) {\n node.__setValueState(ValueState.Negative, constraintMessage);\n }\n } else {\n node.__setValueState(ValueState.None, ['']);\n }\n }\n\n /**\n * Receives all constraints of a node. Use this in your custom validators or components.\n */\n public __getConstraints(): FieldConstraints | undefined {\n if (this.__meta.isArrayNode && this.__parentNode?.__parentNode) {\n const fieldDescriptor =\n this.__parentNode.__parentNode.__meta.nodeFields.find(\n f => f.fieldName === this.__parentNode!.__meta.fieldName,\n );\n return fieldDescriptor?.constraints;\n }\n\n if (this.__parentNode) {\n const fieldDescriptor = this.__parentNode.__meta.nodeFields.find(\n f => f.fieldName === this.__meta.fieldName,\n );\n return fieldDescriptor?.constraints;\n }\n return undefined;\n }\n\n /**\n * Set the value state\n * @param {ValueState} state - The state of the node.\n * @param {string[]} messageAndParams - Description for the formatter.\n */\n __setValueState(state: ValueState, messageAndParams: string[]) {\n const shouldNotify = this.__meta.valueState !== state;\n this.__meta.valueState = state;\n this.__meta.stateMessage = OPEN_MODELS_OPTIONS.valueStateMessageFormatter(\n messageAndParams[0],\n ...messageAndParams.slice(1),\n );\n // set invalid on error state\n // the event is sent from ...\n this.__meta.isValid = state !== ValueState.Negative;\n\n if (shouldNotify) {\n this.__dispatchEvent(\n new CustomEvent('state-changed', {\n detail: this,\n bubbles: false,\n }),\n );\n }\n }\n\n /**\n * Resets the node to the last inserted literal or to the initial state.\n * // todo: reset to default values not just the empty state\n */\n public __reset() {\n if (this.__meta.initialValue !== undefined) {\n this.__updateWithLiteral(this.__meta.initialValue);\n this.__meta.isPristine = true;\n return;\n }\n // else re init every field downwards\n this.__clear();\n this.__meta.isPristine = true;\n }\n\n /**\n * Clear clears the element downwards and set __isEmpty to true on all sub nodes.\n *\n * A cleared field is not populated on `__toLiteral` or `__toJson` when the option `EmitUnpopulated` or `EmitDefaultValues` is set to false.\n */\n public __clear(withoutNotification: boolean = false) {\n this.__isEmpty = true;\n\n // __clear every childNode too\n this.__meta.nodeFields.forEach(descriptor => {\n (\n this[`_${descriptor.fieldName}` as keyof FieldNode] as FieldNode\n ).__clear(withoutNotification);\n });\n if (!withoutNotification) {\n this.__notifyFieldValueChange(false);\n }\n // todo: set to values to default value or initial\n // todo: set state to None\n // todo: set valid to true\n }\n\n /**\n * Helper method to update a skalar / primitive field of a type. Used by the generated models.\n * Triggers also the validation and clearance, if needed.\n *\n * @param {FieldNode} targetNode - The field of a FieldNode\n * @param {string | boolean | number} value - The value you want to set\n * @protected\n */\n // eslint-disable-next-line class-methods-use-this\n protected __PrimitivesSetter(targetNode: IPrimitive, value: unknown) {\n // do not do anything if current value equals val\n if (targetNode._value !== value) {\n targetNode._value = value; // eslint-disable-line no-param-reassign\n\n targetNode.__isEmpty = false; // eslint-disable-line no-param-reassign\n this.__validateBottomUp(targetNode);\n targetNode.__notifyFieldValueChange(true);\n }\n }\n\n /**\n * Helper method to update a field of a type. Used by the generated models.\n * Triggers also the validation and clearance, if needed.\n *\n * @param {FieldNode} targetNode - The field of a FieldNode\n * @param {} literalData - The literal type matches the interface from ITypeName.\n * @protected\n */\n // eslint-disable-next-line class-methods-use-this\n protected __TypeSetter(\n targetNode: FieldNode,\n literalData: unknown | undefined | null,\n ) {\n if (literalData === undefined || literalData === null) {\n targetNode.__clear();\n this.__validateBottomUp(targetNode);\n targetNode.__notifyFieldValueChange(true);\n return;\n }\n\n targetNode.__updateWithLiteral(literalData); // keep the references by getting the values\n // this is the parent of the target_node\n targetNode.___updateNotEmptyPath();\n this.__validateBottomUp(targetNode);\n targetNode.__notifyFieldValueChange(true);\n }\n\n /**\n * Notifies field changes\n * @param bubbles\n * @protected\n */\n protected __notifyFieldValueChange(bubbles?: boolean) {\n this.__dispatchEvent(\n new CustomEvent('this-field-value-changed', {\n detail: this,\n bubbles: false,\n }),\n );\n\n if (bubbles) {\n this.__rootNode.__meta.isPristine = false;\n // todo check if nodes in between this and root should be set to false too\n // check ARRAY.ts line 120 too\n this.__meta.isPristine = false;\n\n // console.log('bubble', this.__meta.typeName)\n this.__dispatchEvent(\n new CustomEvent('field-value-changed', {\n detail: this,\n bubbles: true,\n }),\n );\n this.__dispatchEvent(\n new CustomEvent('update', {\n detail: this,\n bubbles: true,\n }),\n );\n } else {\n // triggered on clear or fromLiteral\n this.__dispatchEvent(\n new CustomEvent('field-value-updated', {\n detail: this,\n bubbles: false,\n }),\n );\n\n this.__dispatchEvent(\n new CustomEvent('update', {\n detail: this,\n bubbles: false,\n }),\n );\n }\n }\n\n /**\n * Returns the child nodes of a node.\n */\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n public get __childNodes(): any[] {\n return this.__meta.nodeFields.map(\n field => this[field.fieldName as keyof FieldNode],\n );\n }\n\n /**\n * Broadcast an event to all child nodes of a field node.\n * @param event\n */\n __broadcastEvent(event: CustomEvent) {\n // trigger the local listeners\n this.__triggerNodeEvents(event);\n\n // dispatch to children\n this.__childNodes.forEach(child => {\n if (child instanceof FieldNode) {\n child.__broadcastEvent(event);\n }\n });\n }\n\n /**\n * Dispatches a custom event on a FieldNode\n * @param {CustomEvent} event - A generic custom event.\n */\n __dispatchEvent(event: CustomEvent): CustomEvent {\n // trigger the events on current node\n this.__triggerNodeEvents(event);\n\n // go to parent\n if (event.bubbles && this.__parentNode !== undefined) {\n return this.__parentNode.__dispatchEvent(event);\n }\n return event;\n }\n\n /**\n * Helper method to invoke/execute the event on the current node\n * @param event\n * @protected\n */\n protected __triggerNodeEvents(event: CustomEvent<FieldNode>) {\n if (\n this.__meta.eventListener.has(event.type) &&\n this.__meta.eventListener.get(event.type)!.length > 0\n ) {\n this.__meta.eventListener\n .get(event.type)!\n .forEach((t, i, listenerArray) => {\n t.callbackfn(event);\n if (\n t.options !== undefined &&\n typeof t.options !== 'boolean' &&\n t.options.once\n ) {\n // eslint-disable-next-line no-param-reassign\n delete listenerArray[i];\n }\n });\n }\n }\n\n /**\n * Add a handler to a node\n * @param {string} type - A case-sensitive string representing the event type to listen for.\n * @param {function} listener - The object that receives a notification (an object that implements the Event interface) when an event of the specified type occurs. This must be null, an object with a handleEvent() method, or a JavaScript function. See The event listener callback for details on the callback itself.\n * @param {} options - An object that specifies characteristics about the event listener. \\n\\nThe available option is `once:boolean`\n */\n public __addEventListener(\n type: ModelEventType,\n listener: CustomEventListener,\n options?: boolean | AddEventListenerOptions,\n ): void {\n if (!this.__meta.eventListener.has(type)) {\n this.__meta.eventListener.set(type, []);\n }\n this.__meta.eventListener\n .get(type)!\n .push({ callbackfn: listener, options });\n }\n\n // add a listener for a custom event, defined and triggered by yourself\n // this could be something like 'focus-requested'\n public __addCustomEventListener(\n type: string,\n handler: CustomEventListener,\n options?: boolean | AddEventListenerOptions,\n ): void {\n if (!this.__meta.eventListener.has(type)) {\n this.__meta.eventListener.set(type, []);\n }\n this.__meta.eventListener.get(type)!.push({ callbackfn: handler, options });\n }\n\n /**\n * Removes the handler from a node\n * @param type\n * @param handler\n * @param options\n */\n public __removeEventListener(\n type: ModelEventType,\n handler: CustomEventListener,\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n options?: boolean | EventListenerOptions,\n ): void {\n if (this.__meta.eventListener.has(type)) {\n this.__meta.eventListener.set(\n type,\n this.__meta.eventListener\n .get(type)!\n .filter(e => e.callbackfn !== handler),\n );\n }\n }\n\n /**\n * Removes the handler from a node\n * @param type\n * @param handler\n * @param options\n */\n public __removeCustomEventListener(\n type: string,\n handler: CustomEventListener,\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n options?: boolean | EventListenerOptions,\n ): void {\n if (this.__meta.eventListener.has(type)) {\n this.__meta.eventListener.set(\n type,\n this.__meta.eventListener\n .get(type)!\n .filter(e => e.callbackfn !== handler),\n );\n }\n }\n\n /**\n * if some child is not empty, set isEmpty to false, all the way up to the root node\n * @private\n */\n protected ___updateNotEmptyPath() {\n this.___isEmpty = false;\n if (this.__parentNode !== undefined && this.__parentNode.__isEmpty) {\n this.__parentNode.___updateNotEmptyPath();\n }\n }\n\n // eslint-disable-next-line class-methods-use-this\n protected __checkConstraints(\n fieldConstraints: FieldConstraints,\n ): string[] | undefined {\n if (fieldConstraints.required) {\n if (this.__isEmpty) {\n return ['constraint.violation.required'];\n }\n }\n return undefined;\n }\n\n // eslint-disable-next-line class-methods-use-this\n private __toLowerCamelCase(string: string) {\n if (OPEN_MODELS_OPTIONS.UseProtoNames) {\n const [start, ...rest] = (\n string[0] === '_' ? string.replace('_', 'X') : string\n ).split('_');\n return (\n start +\n rest\n .map(s => {\n if (s.length === 0) return '';\n return s[0].toUpperCase() + s.slice(1);\n })\n .join('')\n );\n }\n return string;\n }\n\n // eslint-disable-next-line class-methods-use-this\n protected __toLowerCamelCaseWithoutXPrefix(string: string) {\n if (OPEN_MODELS_OPTIONS.UseProtoNames) {\n const [start, ...rest] = (\n string[0] === '_' ? string.replace('_', 'X') : string\n ).split('_');\n return (\n start +\n rest\n .map(s => {\n if (s.length === 0) return '';\n return s[0].toUpperCase() + s.slice(1);\n })\n .join('')\n );\n }\n return string;\n }\n\n // eslint-disable-next-line class-methods-use-this\n private __toSnakeCase(string: string): string {\n return string\n .split(/(?=[A-Z])/)\n .map(word => word.toLowerCase())\n .join('_');\n }\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FieldBindings.js","sourceRoot":"","sources":["../../src/decorators/FieldBindings.ts"],"names":[],"mappings":"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","sourcesContent":["/* eslint-disable no-param-reassign */\nimport { LitElement, ReactiveElement } from \"lit\";\n\nimport type { ModelEventType } from \"./ModelDecorators\";\n\n// ─────────────────────────────────────────────────────────────────\n// Types\n// ─────────────────────────────────────────────────────────────────\n\n/**\n * Interface for FieldNode-like objects that support event listening.\n */\nexport interface FieldNodeLike {\n __addEventListener(type: string, listener: (e: CustomEvent) => void): void;\n __removeEventListener(type: string, listener: (e: CustomEvent) => void): void;\n __meta?: { typeName?: string };\n value?: unknown;\n}\n\n/**\n * Interface for components that bind to FieldNode models.\n *\n * Components implement `modelReaders` and `modelWriters` maps\n * keyed by `__meta.typeName` (e.g., \"primitives.STRING\", \"furo.fat.String\").\n *\n * @example\n * ```typescript\n * export class MyInput extends LitElement implements BindableComponent {\n * @fieldBindings.model()\n * model: STRING | XString | undefined;\n *\n * // Provided by decorator\n * declare writeToModel: () => void;\n *\n * modelReaders = new Map<string, () => void>([\n * [\"primitives.STRING\", () => { this.value = (this.model as STRING).value ?? \"\"; }],\n * [\"furo.fat.String\", () => { this.value = (this.model as XString).value.value ?? \"\"; }],\n * ]);\n *\n * modelWriters = new Map<string, () => void>([\n * [\"primitives.STRING\", () => { (this.model as STRING).value = this.value; }],\n * [\"furo.fat.String\", () => { (this.model as XString).value.value = this.value; }],\n * ]);\n * }\n * ```\n */\nexport interface BindableComponent extends LitElement {\n model: FieldNodeLike | undefined;\n\n /** Map of typeName → reader function (model → component) */\n modelReaders: Map<string, () => void>;\n\n /** Map of typeName → writer function (component → model) */\n modelWriters: Map<string, () => void>;\n\n /** Helper to write current value to model (provided by decorator) */\n writeToModel: () => void;\n}\n\n// ─────────────────────────────────────────────────────────────────\n// Metadata Storage\n// ─────────────────────────────────────────────────────────────────\n\ninterface FieldEventMeta {\n propertyKey: string;\n eventType: ModelEventType;\n // eslint-disable-next-line @typescript-eslint/no-unsafe-function-type\n method: Function;\n}\n\n// Symbol keys for class metadata\nconst FIELD_EVENTS = Symbol.for(\"__fieldEvents__\");\n\n// Symbol keys for instance storage\nconst FIELD_LISTENERS = Symbol.for(\"__fieldListeners__\");\nconst FIELD_PATCHED = Symbol.for(\"__fieldPatched__\");\nconst CURRENT_MODEL = Symbol.for(\"__currentModel__\");\nconst MODEL_WRITE_FN = Symbol.for(\"__modelWriteFn__\");\nconst MODEL_READ_FN = Symbol.for(\"__modelReadFn__\");\n\n// ─────────────────────────────────────────────────────────────────\n// fieldBindings - Decorators for Reusable Bindable Components\n// ─────────────────────────────────────────────────────────────────\n\n/**\n * ### fieldBindings\n *\n * Decorators for creating reusable components that bind to FieldNode models.\n *\n * The component provides `modelReaders` and `modelWriters` maps keyed by\n * `__meta.typeName`. The decorator handles:\n * - Binding/unbinding on model change\n * - Calling the correct reader when model value changes\n * - Providing `writeToModel()` method that calls the correct writer\n *\n * @example\n * ```typescript\n * export class MyInput extends LitElement implements BindableComponent {\n * @fieldBindings.model()\n * model: STRING | XString | undefined;\n *\n * declare writeToModel: () => void;\n *\n * modelReaders = new Map([\n * [\"primitives.STRING\", () => { this.value = (this.model as STRING).value ?? \"\"; }],\n * [\"furo.fat.String\", () => { this.value = (this.model as XString).value.value ?? \"\"; }],\n * ]);\n *\n * modelWriters = new Map([\n * [\"primitives.STRING\", () => { (this.model as STRING).value = this.value; }],\n * [\"furo.fat.String\", () => { (this.model as XString).value.value = this.value; }],\n * ]);\n *\n * private _onInput(e: Event) {\n * this.value = (e.target as HTMLInputElement).value;\n * this.writeToModel();\n * }\n * }\n * ```\n */\nexport const fieldBindings = {\n /**\n * Decorator for the `model` property.\n *\n * Handles:\n * - Binding/unbinding when model changes\n * - Resolving reader/writer functions based on model type\n * - Calling reader on model value changes\n * - Providing `writeToModel()` method\n */\n model() {\n return function modelDecorator<T extends FieldNodeLike>(target: object, propertyKey: string) {\n const ctor = target.constructor as typeof ReactiveElement;\n\n // Patch lifecycle\n patchLifecycle(ctor);\n\n // Add writeToModel helper method\n if (!Object.prototype.hasOwnProperty.call(target, \"writeToModel\")) {\n Object.defineProperty(target, \"writeToModel\", {\n value: function writeToModel(this: LitElement & Record<symbol, (() => void) | undefined>) {\n const writeFn = this[MODEL_WRITE_FN];\n if (writeFn) {\n try {\n writeFn();\n } catch (e) {\n // eslint-disable-next-line no-console\n console.error(\"Failed to write to model:\", e);\n }\n }\n },\n writable: false,\n enumerable: false,\n configurable: true,\n });\n }\n\n // Create getter/setter for the model property\n Object.defineProperty(target, propertyKey, {\n get(this: LitElement & Record<symbol, T | undefined>): T | undefined {\n return this[CURRENT_MODEL];\n },\n set(this: LitElement & BindableComponent & Record<symbol, T | (() => void) | undefined>, value: T | undefined) {\n const oldModel = this[CURRENT_MODEL] as T | undefined;\n if (value === oldModel) return;\n\n // Unbind from old model\n if (oldModel) {\n unbindFromModel(this, oldModel);\n }\n\n // Store new model\n this[CURRENT_MODEL] = value;\n\n // Resolve reader/writer functions based on type\n if (value) {\n const typeName = value.__meta?.typeName ?? \"primitives.STRING\";\n\n // Resolve reader\n const reader = this.modelReaders?.get(typeName);\n if (reader) {\n this[MODEL_READ_FN] = reader.bind(this);\n } else {\n // eslint-disable-next-line no-console\n console.warn(`No modelReader for type \"${typeName}\". Available: ${[...(this.modelReaders?.keys() ?? [])].join(\", \")}`);\n this[MODEL_READ_FN] = undefined;\n }\n\n // Resolve writer\n const writer = this.modelWriters?.get(typeName);\n if (writer) {\n this[MODEL_WRITE_FN] = writer.bind(this);\n } else {\n // eslint-disable-next-line no-console\n console.warn(`No modelWriter for type \"${typeName}\". Available: ${[...(this.modelWriters?.keys() ?? [])].join(\", \")}`);\n this[MODEL_WRITE_FN] = undefined;\n }\n } else {\n this[MODEL_READ_FN] = undefined;\n this[MODEL_WRITE_FN] = undefined;\n }\n\n // Bind to new model (if connected)\n if (value && this.isConnected) {\n bindToModel(this, value);\n }\n\n // Trigger Lit update\n this.requestUpdate();\n },\n enumerable: true,\n configurable: true,\n });\n };\n },\n\n /**\n * Binds a method to an event on the model.\n * When the event fires, the method is called with the event detail.\n *\n * @param eventType - The event type to listen for\n */\n onEvent(eventType: ModelEventType) {\n return function onEventDecorator(target: object, propertyKey: string, descriptor: PropertyDescriptor) {\n const originalMethod = descriptor.value;\n const ctor = target.constructor as typeof ReactiveElement;\n\n let events = (ctor as unknown as Record<symbol, FieldEventMeta[]>)[FIELD_EVENTS];\n if (!events) {\n events = [];\n (ctor as unknown as Record<symbol, FieldEventMeta[]>)[FIELD_EVENTS] = events;\n }\n events.push({ propertyKey, eventType, method: originalMethod });\n\n patchLifecycle(ctor);\n };\n },\n};\n\n// ─────────────────────────────────────────────────────────────────\n// Binding Logic\n// ─────────────────────────────────────────────────────────────────\n\ninterface ListenerEntry {\n eventType: string;\n listener: (e: CustomEvent) => void;\n}\n\ntype ComponentWithListeners = LitElement & BindableComponent & Record<symbol, Map<string, ListenerEntry> | FieldNodeLike | (() => void) | undefined>;\n\n/**\n * Bind to the model - set up event listeners and call initial read.\n */\nfunction bindToModel(component: ComponentWithListeners, model: FieldNodeLike): void {\n const ctor = component.constructor as typeof ReactiveElement;\n const events = (ctor as unknown as Record<symbol, FieldEventMeta[]>)[FIELD_EVENTS] ?? [];\n\n const listeners = new Map<string, ListenerEntry>();\n component[FIELD_LISTENERS] = listeners;\n\n // Get the pre-resolved read function\n const readFn = component[MODEL_READ_FN] as (() => void) | undefined;\n\n // Set up value change listener - calls the reader\n if (readFn) {\n const valueListener = () => {\n readFn();\n };\n\n listeners.set(\"value\", { eventType: \"this-field-value-changed\", listener: valueListener });\n model.__addEventListener(\"this-field-value-changed\", valueListener);\n\n // Initial read\n readFn();\n }\n\n // Set up event bindings from @fieldBindings.onEvent decorators\n events.forEach(({ propertyKey, eventType, method }) => {\n const listener = (e: CustomEvent) => {\n method.call(component, e.detail);\n };\n\n listeners.set(`event:${propertyKey}`, { eventType, listener });\n model.__addEventListener(eventType, listener);\n });\n}\n\n/**\n * Unbind all listeners from the model.\n */\nfunction unbindFromModel(component: ComponentWithListeners, model: FieldNodeLike): void {\n const listeners = component[FIELD_LISTENERS] as Map<string, ListenerEntry> | undefined;\n if (!listeners) return;\n\n listeners.forEach(({ eventType, listener }) => {\n model.__removeEventListener(eventType, listener);\n });\n listeners.clear();\n}\n\n// ─────────────────────────────────────────────────────────────────\n// Lifecycle Patching\n// ─────────────────────────────────────────────────────────────────\n\n/**\n * Patch connectedCallback/disconnectedCallback to handle model binding.\n */\nfunction patchLifecycle(ctor: typeof ReactiveElement): void {\n if ((ctor as unknown as Record<symbol, boolean>)[FIELD_PATCHED]) {\n return;\n }\n (ctor as unknown as Record<symbol, boolean>)[FIELD_PATCHED] = true;\n\n const originalConnected = ctor.prototype.connectedCallback;\n const originalDisconnected = ctor.prototype.disconnectedCallback;\n\n ctor.prototype.connectedCallback = function connectedCallback(this: ComponentWithListeners) {\n originalConnected?.call(this);\n\n // Bind to model if already set\n const model = this[CURRENT_MODEL] as FieldNodeLike | undefined;\n if (model) {\n bindToModel(this, model);\n }\n };\n\n ctor.prototype.disconnectedCallback = function disconnectedCallback(this: ComponentWithListeners) {\n // Unbind from model\n const model = this[CURRENT_MODEL] as FieldNodeLike | undefined;\n if (model) {\n unbindFromModel(this, model);\n }\n\n originalDisconnected?.call(this);\n };\n}\n"]}
|
|
1
|
+
{"version":3,"file":"FieldBindings.js","sourceRoot":"","sources":["../../src/decorators/FieldBindings.ts"],"names":[],"mappings":"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","sourcesContent":["/* eslint-disable no-param-reassign */\nimport { LitElement, ReactiveElement } from \"lit\";\n\nimport type { ModelEventType } from '@/FieldNode';\n\n// ─────────────────────────────────────────────────────────────────\n// Types\n// ─────────────────────────────────────────────────────────────────\n\n/**\n * Interface for FieldNode-like objects that support event listening.\n */\nexport interface FieldNodeLike {\n __addEventListener(type: string, listener: (e: CustomEvent) => void): void;\n __removeEventListener(type: string, listener: (e: CustomEvent) => void): void;\n __meta?: { typeName?: string };\n value?: unknown;\n}\n\n/**\n * Interface for components that bind to FieldNode models.\n *\n * Components implement `modelReaders` and `modelWriters` maps\n * keyed by `__meta.typeName` (e.g., \"primitives.STRING\", \"furo.fat.String\").\n *\n * @example\n * ```typescript\n * export class MyInput extends LitElement implements BindableComponent {\n * @fieldBindings.model()\n * model: STRING | XString | undefined;\n *\n * // Provided by decorator\n * declare writeToModel: () => void;\n *\n * modelReaders = new Map<string, () => void>([\n * [\"primitives.STRING\", () => { this.value = (this.model as STRING).value ?? \"\"; }],\n * [\"furo.fat.String\", () => { this.value = (this.model as XString).value.value ?? \"\"; }],\n * ]);\n *\n * modelWriters = new Map<string, () => void>([\n * [\"primitives.STRING\", () => { (this.model as STRING).value = this.value; }],\n * [\"furo.fat.String\", () => { (this.model as XString).value.value = this.value; }],\n * ]);\n * }\n * ```\n */\nexport interface BindableComponent extends LitElement {\n model: FieldNodeLike | undefined;\n\n /** Map of typeName → reader function (model → component) */\n modelReaders: Map<string, () => void>;\n\n /** Map of typeName → writer function (component → model) */\n modelWriters: Map<string, () => void>;\n\n /** Helper to write current value to model (provided by decorator) */\n writeToModel: () => void;\n}\n\n// ─────────────────────────────────────────────────────────────────\n// Metadata Storage\n// ─────────────────────────────────────────────────────────────────\n\ninterface FieldEventMeta {\n propertyKey: string;\n eventType: ModelEventType;\n // eslint-disable-next-line @typescript-eslint/no-unsafe-function-type\n method: Function;\n}\n\n// Symbol keys for class metadata\nconst FIELD_EVENTS = Symbol.for(\"__fieldEvents__\");\n\n// Symbol keys for instance storage\nconst FIELD_LISTENERS = Symbol.for(\"__fieldListeners__\");\nconst FIELD_PATCHED = Symbol.for(\"__fieldPatched__\");\nconst CURRENT_MODEL = Symbol.for(\"__currentModel__\");\nconst MODEL_WRITE_FN = Symbol.for(\"__modelWriteFn__\");\nconst MODEL_READ_FN = Symbol.for(\"__modelReadFn__\");\n\n// ─────────────────────────────────────────────────────────────────\n// fieldBindings - Decorators for Reusable Bindable Components\n// ─────────────────────────────────────────────────────────────────\n\n/**\n * ### fieldBindings\n *\n * Decorators for creating reusable components that bind to FieldNode models.\n *\n * The component provides `modelReaders` and `modelWriters` maps keyed by\n * `__meta.typeName`. The decorator handles:\n * - Binding/unbinding on model change\n * - Calling the correct reader when model value changes\n * - Providing `writeToModel()` method that calls the correct writer\n *\n * @example\n * ```typescript\n * export class MyInput extends LitElement implements BindableComponent {\n * @fieldBindings.model()\n * model: STRING | XString | undefined;\n *\n * declare writeToModel: () => void;\n *\n * modelReaders = new Map([\n * [\"primitives.STRING\", () => { this.value = (this.model as STRING).value ?? \"\"; }],\n * [\"furo.fat.String\", () => { this.value = (this.model as XString).value.value ?? \"\"; }],\n * ]);\n *\n * modelWriters = new Map([\n * [\"primitives.STRING\", () => { (this.model as STRING).value = this.value; }],\n * [\"furo.fat.String\", () => { (this.model as XString).value.value = this.value; }],\n * ]);\n *\n * private _onInput(e: Event) {\n * this.value = (e.target as HTMLInputElement).value;\n * this.writeToModel();\n * }\n * }\n * ```\n */\nexport const fieldBindings = {\n /**\n * Decorator for the `model` property.\n *\n * Handles:\n * - Binding/unbinding when model changes\n * - Resolving reader/writer functions based on model type\n * - Calling reader on model value changes\n * - Providing `writeToModel()` method\n */\n model() {\n return function modelDecorator<T extends FieldNodeLike>(target: object, propertyKey: string) {\n const ctor = target.constructor as typeof ReactiveElement;\n\n // Patch lifecycle\n patchLifecycle(ctor);\n\n // Add writeToModel helper method\n if (!Object.prototype.hasOwnProperty.call(target, \"writeToModel\")) {\n Object.defineProperty(target, \"writeToModel\", {\n value: function writeToModel(this: LitElement & Record<symbol, (() => void) | undefined>) {\n const writeFn = this[MODEL_WRITE_FN];\n if (writeFn) {\n try {\n writeFn();\n } catch (e) {\n // eslint-disable-next-line no-console\n console.error(\"Failed to write to model:\", e);\n }\n }\n },\n writable: false,\n enumerable: false,\n configurable: true,\n });\n }\n\n // Create getter/setter for the model property\n Object.defineProperty(target, propertyKey, {\n get(this: LitElement & Record<symbol, T | undefined>): T | undefined {\n return this[CURRENT_MODEL];\n },\n set(this: LitElement & BindableComponent & Record<symbol, T | (() => void) | undefined>, value: T | undefined) {\n const oldModel = this[CURRENT_MODEL] as T | undefined;\n if (value === oldModel) return;\n\n // Unbind from old model\n if (oldModel) {\n unbindFromModel(this, oldModel);\n }\n\n // Store new model\n this[CURRENT_MODEL] = value;\n\n // Resolve reader/writer functions based on type\n if (value) {\n const typeName = value.__meta?.typeName ?? \"primitives.STRING\";\n\n // Resolve reader\n const reader = this.modelReaders?.get(typeName);\n if (reader) {\n this[MODEL_READ_FN] = reader.bind(this);\n } else {\n // eslint-disable-next-line no-console\n console.warn(`No modelReader for type \"${typeName}\". Available: ${[...(this.modelReaders?.keys() ?? [])].join(\", \")}`);\n this[MODEL_READ_FN] = undefined;\n }\n\n // Resolve writer\n const writer = this.modelWriters?.get(typeName);\n if (writer) {\n this[MODEL_WRITE_FN] = writer.bind(this);\n } else {\n // eslint-disable-next-line no-console\n console.warn(`No modelWriter for type \"${typeName}\". Available: ${[...(this.modelWriters?.keys() ?? [])].join(\", \")}`);\n this[MODEL_WRITE_FN] = undefined;\n }\n } else {\n this[MODEL_READ_FN] = undefined;\n this[MODEL_WRITE_FN] = undefined;\n }\n\n // Bind to new model (if connected)\n if (value && this.isConnected) {\n bindToModel(this, value);\n }\n\n // Trigger Lit update\n this.requestUpdate();\n },\n enumerable: true,\n configurable: true,\n });\n };\n },\n\n /**\n * Binds a method to an event on the model.\n * When the event fires, the method is called with the event detail.\n *\n * @param eventType - The event type to listen for\n */\n onEvent(eventType: ModelEventType) {\n return function onEventDecorator(target: object, propertyKey: string, descriptor: PropertyDescriptor) {\n const originalMethod = descriptor.value;\n const ctor = target.constructor as typeof ReactiveElement;\n\n let events = (ctor as unknown as Record<symbol, FieldEventMeta[]>)[FIELD_EVENTS];\n if (!events) {\n events = [];\n (ctor as unknown as Record<symbol, FieldEventMeta[]>)[FIELD_EVENTS] = events;\n }\n events.push({ propertyKey, eventType, method: originalMethod });\n\n patchLifecycle(ctor);\n };\n },\n};\n\n// ─────────────────────────────────────────────────────────────────\n// Binding Logic\n// ─────────────────────────────────────────────────────────────────\n\ninterface ListenerEntry {\n eventType: string;\n listener: (e: CustomEvent) => void;\n}\n\ntype ComponentWithListeners = LitElement & BindableComponent & Record<symbol, Map<string, ListenerEntry> | FieldNodeLike | (() => void) | undefined>;\n\n/**\n * Bind to the model - set up event listeners and call initial read.\n */\nfunction bindToModel(component: ComponentWithListeners, model: FieldNodeLike): void {\n const ctor = component.constructor as typeof ReactiveElement;\n const events = (ctor as unknown as Record<symbol, FieldEventMeta[]>)[FIELD_EVENTS] ?? [];\n\n const listeners = new Map<string, ListenerEntry>();\n component[FIELD_LISTENERS] = listeners;\n\n // Get the pre-resolved read function\n const readFn = component[MODEL_READ_FN] as (() => void) | undefined;\n\n // Set up value change listener - calls the reader\n if (readFn) {\n const valueListener = () => {\n readFn();\n };\n\n listeners.set(\"value\", { eventType: \"this-field-value-changed\", listener: valueListener });\n model.__addEventListener(\"this-field-value-changed\", valueListener);\n\n // Initial read\n readFn();\n }\n\n // Set up event bindings from @fieldBindings.onEvent decorators\n events.forEach(({ propertyKey, eventType, method }) => {\n const listener = (e: CustomEvent) => {\n method.call(component, e.detail);\n };\n\n listeners.set(`event:${propertyKey}`, { eventType, listener });\n model.__addEventListener(eventType, listener);\n });\n}\n\n/**\n * Unbind all listeners from the model.\n */\nfunction unbindFromModel(component: ComponentWithListeners, model: FieldNodeLike): void {\n const listeners = component[FIELD_LISTENERS] as Map<string, ListenerEntry> | undefined;\n if (!listeners) return;\n\n listeners.forEach(({ eventType, listener }) => {\n model.__removeEventListener(eventType, listener);\n });\n listeners.clear();\n}\n\n// ─────────────────────────────────────────────────────────────────\n// Lifecycle Patching\n// ─────────────────────────────────────────────────────────────────\n\n/**\n * Patch connectedCallback/disconnectedCallback to handle model binding.\n */\nfunction patchLifecycle(ctor: typeof ReactiveElement): void {\n if ((ctor as unknown as Record<symbol, boolean>)[FIELD_PATCHED]) {\n return;\n }\n (ctor as unknown as Record<symbol, boolean>)[FIELD_PATCHED] = true;\n\n const originalConnected = ctor.prototype.connectedCallback;\n const originalDisconnected = ctor.prototype.disconnectedCallback;\n\n ctor.prototype.connectedCallback = function connectedCallback(this: ComponentWithListeners) {\n originalConnected?.call(this);\n\n // Bind to model if already set\n const model = this[CURRENT_MODEL] as FieldNodeLike | undefined;\n if (model) {\n bindToModel(this, model);\n }\n };\n\n ctor.prototype.disconnectedCallback = function disconnectedCallback(this: ComponentWithListeners) {\n // Unbind from model\n const model = this[CURRENT_MODEL] as FieldNodeLike | undefined;\n if (model) {\n unbindFromModel(this, model);\n }\n\n originalDisconnected?.call(this);\n };\n}\n"]}
|
|
@@ -1,10 +1,9 @@
|
|
|
1
|
-
|
|
2
|
-
* Event types dispatched by FieldNode models.
|
|
3
|
-
*/
|
|
4
|
-
export type ModelEventType = "update" | "field-value-changed" | "this-field-value-changed" | "field-value-updated" | "this-state-changed" | "state-changed" | "validity-changed" | "array-changed" | "this-array-changed" | "map-changed" | "this-map-changed" | "parent-readonly-set" | "parent-readonly-unset" | "model-injected";
|
|
1
|
+
import type { ModelEventType } from '../FieldNode.js';
|
|
5
2
|
/**
|
|
6
3
|
* Event map for FieldNode model events.
|
|
7
4
|
* Most events don't have detail - they just notify that something changed.
|
|
5
|
+
*
|
|
6
|
+
* This may look like a copy of the ModelEventType, but is needed for the implementation.
|
|
8
7
|
*/
|
|
9
8
|
export interface ModelEventMap {
|
|
10
9
|
update: undefined;
|
|
@@ -32,17 +31,17 @@ interface FieldNodeLike {
|
|
|
32
31
|
value?: unknown;
|
|
33
32
|
}
|
|
34
33
|
/**
|
|
35
|
-
* ###
|
|
34
|
+
* ### ModelBindings Factory
|
|
36
35
|
*
|
|
37
36
|
* Creates type-safe decorators bound to a specific FieldNode model.
|
|
38
37
|
* Use this to bind component properties and methods to model events.
|
|
39
38
|
*
|
|
40
39
|
* Usage:
|
|
41
40
|
* ```typescript
|
|
42
|
-
* import {
|
|
41
|
+
* import { ModelBindings } from "@x/furo/open-models/ModelDecorators";
|
|
43
42
|
* import { CubeEntityModel } from "./CubeEntityModel";
|
|
44
43
|
*
|
|
45
|
-
* const cubeModel =
|
|
44
|
+
* const cubeModel = ModelBindings(CubeEntityModel.model);
|
|
46
45
|
*
|
|
47
46
|
* class MyComponent extends LitElement {
|
|
48
47
|
* // Bind to a nested field value - updates when cube.length changes
|
|
@@ -6,20 +6,20 @@ const MODEL_BIND_PATCHED = Symbol.for("__modelBindPatched__");
|
|
|
6
6
|
const MODEL_EVENT_PATCHED = Symbol.for("__modelEventPatched__");
|
|
7
7
|
const MODEL_EVENT_METHODS = Symbol.for("__modelEventMethods__");
|
|
8
8
|
// ─────────────────────────────────────────────────────────────────
|
|
9
|
-
//
|
|
9
|
+
// ModelBindings Factory
|
|
10
10
|
// ─────────────────────────────────────────────────────────────────
|
|
11
11
|
/**
|
|
12
|
-
* ###
|
|
12
|
+
* ### ModelBindings Factory
|
|
13
13
|
*
|
|
14
14
|
* Creates type-safe decorators bound to a specific FieldNode model.
|
|
15
15
|
* Use this to bind component properties and methods to model events.
|
|
16
16
|
*
|
|
17
17
|
* Usage:
|
|
18
18
|
* ```typescript
|
|
19
|
-
* import {
|
|
19
|
+
* import { ModelBindings } from "@x/furo/open-models/ModelDecorators";
|
|
20
20
|
* import { CubeEntityModel } from "./CubeEntityModel";
|
|
21
21
|
*
|
|
22
|
-
* const cubeModel =
|
|
22
|
+
* const cubeModel = ModelBindings(CubeEntityModel.model);
|
|
23
23
|
*
|
|
24
24
|
* class MyComponent extends LitElement {
|
|
25
25
|
* // Bind to a nested field value - updates when cube.length changes
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ModelDecorators.js","sourceRoot":"","sources":["../../src/decorators/ModelDecorators.ts"],"names":[],"mappings":"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","sourcesContent":["/* eslint-disable no-param-reassign */\nimport { LitElement, ReactiveElement } from \"lit\";\n\n// ─────────────────────────────────────────────────────────────────\n// Types\n// ─────────────────────────────────────────────────────────────────\n\n/**\n * Event types dispatched by FieldNode models.\n */\nexport type ModelEventType =\n | \"update\"\n | \"field-value-changed\"\n | \"this-field-value-changed\"\n | \"field-value-updated\"\n | \"this-state-changed\"\n | \"state-changed\"\n | \"validity-changed\"\n | \"array-changed\"\n | \"this-array-changed\"\n | \"map-changed\"\n | \"this-map-changed\"\n | \"parent-readonly-set\"\n | \"parent-readonly-unset\"\n | \"model-injected\";\n\n/**\n * Event map for FieldNode model events.\n * Most events don't have detail - they just notify that something changed.\n */\nexport interface ModelEventMap {\n update: undefined;\n \"field-value-changed\": unknown;\n \"this-field-value-changed\": undefined;\n \"field-value-updated\": unknown;\n \"this-state-changed\": undefined;\n \"state-changed\": unknown;\n \"validity-changed\": undefined;\n \"array-changed\": unknown;\n \"this-array-changed\": undefined;\n \"map-changed\": unknown;\n \"this-map-changed\": undefined;\n \"parent-readonly-set\": undefined;\n \"parent-readonly-unset\": undefined;\n \"model-injected\": undefined;\n}\n\n/**\n * Interface for FieldNode-like objects that support event listening and path navigation.\n */\ninterface FieldNodeLike {\n __addEventListener(type: string, listener: (e: CustomEvent) => void): void;\n __removeEventListener(type: string, listener: (e: CustomEvent) => void): void;\n __getFieldNodeByPath?(path: string): FieldNodeLike | undefined;\n value?: unknown;\n}\n\n// ─────────────────────────────────────────────────────────────────\n// Metadata Storage\n// ─────────────────────────────────────────────────────────────────\n\ninterface BindingMeta {\n model: FieldNodeLike;\n path: string;\n eventType: ModelEventType;\n}\nconst bindingsMetadata = new WeakMap<object, Map<string, BindingMeta>>();\n\ninterface EventBindingMeta {\n propertyKey: string;\n model: FieldNodeLike;\n path: string | null;\n eventType: ModelEventType;\n // eslint-disable-next-line @typescript-eslint/no-unsafe-function-type\n method: Function;\n}\n\n// Symbol keys for instance storage\nconst MODEL_BIND_LISTENERS = Symbol.for(\"__modelBindListeners__\");\nconst MODEL_EVENT_LISTENERS = Symbol.for(\"__modelEventListeners__\");\nconst MODEL_BIND_PATCHED = Symbol.for(\"__modelBindPatched__\");\nconst MODEL_EVENT_PATCHED = Symbol.for(\"__modelEventPatched__\");\nconst MODEL_EVENT_METHODS = Symbol.for(\"__modelEventMethods__\");\n\n// ─────────────────────────────────────────────────────────────────\n// modelBindings Factory\n// ─────────────────────────────────────────────────────────────────\n\n/**\n * ### modelBindings Factory\n *\n * Creates type-safe decorators bound to a specific FieldNode model.\n * Use this to bind component properties and methods to model events.\n *\n * Usage:\n * ```typescript\n * import { modelBindings } from \"@x/furo/open-models/ModelDecorators\";\n * import { CubeEntityModel } from \"./CubeEntityModel\";\n *\n * const cubeModel = modelBindings(CubeEntityModel.model);\n *\n * class MyComponent extends LitElement {\n * // Bind to a nested field value - updates when cube.length changes\n * @cubeModel.bind(\"cube.length\")\n * @state()\n * private cubeLength: number = 0;\n *\n * // Bind to model validity\n * @cubeModel.bind(\"__isValid\", \"validity-changed\")\n * @state()\n * private isValid: boolean = true;\n *\n * // React to any field value change on the model\n * @cubeModel.onEvent(\"field-value-changed\")\n * private onAnyFieldChanged() {\n * console.log(\"Something changed!\");\n * }\n *\n * // React to a specific field's changes\n * @cubeModel.onFieldEvent(\"cube.length\", \"this-field-value-changed\")\n * private onLengthChanged() {\n * console.log(\"Length changed!\");\n * }\n * }\n * ```\n *\n * @param model - The FieldNode model to bind to\n * @returns Object with `bind`, `onEvent`, and `onFieldEvent` decorator factories\n */\nexport function ModelBindings<TEventMap extends ModelEventMap = ModelEventMap>(model: FieldNodeLike) {\n return {\n /**\n * Binds a component property to a model field value.\n * When the field changes, the property is automatically updated.\n *\n * @param path - Path to the field (e.g., \"cube.length\", \"__isValid\")\n * @param eventType - Event to listen for (defaults to \"this-field-value-changed\")\n */\n bind(path: string, eventType: ModelEventType = \"this-field-value-changed\") {\n return function bindDecorator(target: object, propertyKey: string) {\n let metadata = bindingsMetadata.get(target);\n if (!metadata) {\n metadata = new Map();\n bindingsMetadata.set(target, metadata);\n }\n metadata.set(propertyKey, { model, path, eventType });\n\n patchBindLifecycle(target.constructor as typeof ReactiveElement);\n };\n },\n\n /**\n * Binds a method to an event on the root model.\n * When the event fires, the method is called.\n *\n * @param eventType - The event type to listen for\n */\n onEvent<K extends keyof TEventMap & ModelEventType>(eventType: K) {\n return function onEventDecorator(target: object, propertyKey: string, descriptor: PropertyDescriptor) {\n const originalMethod = descriptor.value;\n const ctor = target.constructor as typeof ReactiveElement;\n\n let methods = (ctor as unknown as Record<symbol, EventBindingMeta[]>)[MODEL_EVENT_METHODS];\n if (!methods) {\n methods = [];\n (ctor as unknown as Record<symbol, EventBindingMeta[]>)[MODEL_EVENT_METHODS] = methods;\n }\n methods.push({ propertyKey, model, path: null, eventType, method: originalMethod });\n\n patchEventLifecycle(ctor);\n };\n },\n\n /**\n * Binds a method to an event on a specific field.\n * When the event fires on that field, the method is called.\n *\n * @param path - Path to the field (e.g., \"cube.length\")\n * @param eventType - The event type to listen for\n */\n onFieldEvent<K extends keyof TEventMap & ModelEventType>(path: string, eventType: K) {\n return function onFieldEventDecorator(target: object, propertyKey: string, descriptor: PropertyDescriptor) {\n const originalMethod = descriptor.value;\n const ctor = target.constructor as typeof ReactiveElement;\n\n let methods = (ctor as unknown as Record<symbol, EventBindingMeta[]>)[MODEL_EVENT_METHODS];\n if (!methods) {\n methods = [];\n (ctor as unknown as Record<symbol, EventBindingMeta[]>)[MODEL_EVENT_METHODS] = methods;\n }\n methods.push({ propertyKey, model, path, eventType, method: originalMethod });\n\n patchEventLifecycle(ctor);\n };\n },\n };\n}\n\n// ─────────────────────────────────────────────────────────────────\n// Lifecycle Patching\n// ─────────────────────────────────────────────────────────────────\n\n/**\n * Get the field node for a path, handling both direct properties and nested paths.\n */\nfunction getFieldForPath(model: FieldNodeLike, path: string): FieldNodeLike {\n // Check if it's a direct property (starts with __ or no dots)\n if (path.startsWith(\"__\") || !path.includes(\".\")) {\n return model;\n }\n // Navigate to nested field (we trust the field exists per user guarantee)\n if (model.__getFieldNodeByPath) {\n return model.__getFieldNodeByPath(path) as FieldNodeLike;\n }\n return model;\n}\n\n/**\n * Get the value for a path from the model.\n */\nfunction getValueForPath(model: FieldNodeLike, path: string): unknown {\n if (path.startsWith(\"__\")) {\n // Direct property access for internal properties\n return (model as unknown as Record<string, unknown>)[path];\n }\n if (!path.includes(\".\")) {\n // Direct child field\n const field = (model as unknown as Record<string, unknown>)[path] as FieldNodeLike | undefined;\n return field?.value ?? field;\n }\n // Nested path - get the field and return its value\n if (model.__getFieldNodeByPath) {\n const field = model.__getFieldNodeByPath(path);\n return field?.value ?? field;\n }\n return undefined;\n}\n\n/**\n * Patch connectedCallback/disconnectedCallback for bind decorators.\n */\nfunction patchBindLifecycle(ctor: typeof ReactiveElement): void {\n if ((ctor as unknown as Record<symbol, boolean>)[MODEL_BIND_PATCHED]) {\n return;\n }\n (ctor as unknown as Record<symbol, boolean>)[MODEL_BIND_PATCHED] = true;\n\n const originalConnected = ctor.prototype.connectedCallback;\n const originalDisconnected = ctor.prototype.disconnectedCallback;\n\n ctor.prototype.connectedCallback = function connectedCallback(\n this: LitElement & Record<symbol, Map<string, { listener: (e: CustomEvent) => void; field: FieldNodeLike; eventType: string }>>\n ) {\n originalConnected?.call(this);\n\n const metadata = bindingsMetadata.get(Object.getPrototypeOf(this));\n if (!metadata) return;\n\n const listeners = new Map<string, { listener: (e: CustomEvent) => void; field: FieldNodeLike; eventType: string }>();\n this[MODEL_BIND_LISTENERS] = listeners;\n\n metadata.forEach(({ model, path, eventType }, propKey) => {\n const field = getFieldForPath(model, path);\n\n // Set initial value\n (this as unknown as Record<string, unknown>)[propKey] = getValueForPath(model, path);\n\n const listener = () => {\n (this as unknown as Record<string, unknown>)[propKey] = getValueForPath(model, path);\n };\n\n listeners.set(propKey, { listener, field, eventType });\n field.__addEventListener(eventType, listener);\n });\n };\n\n ctor.prototype.disconnectedCallback = function disconnectedCallback(\n this: LitElement & Record<symbol, Map<string, { listener: (e: CustomEvent) => void; field: FieldNodeLike; eventType: string }>>\n ) {\n const listeners = this[MODEL_BIND_LISTENERS];\n if (listeners) {\n listeners.forEach(({ listener, field, eventType }) => {\n field.__removeEventListener(eventType, listener);\n });\n listeners.clear();\n }\n\n originalDisconnected?.call(this);\n };\n}\n\n/**\n * Patch connectedCallback/disconnectedCallback for event decorators.\n */\nfunction patchEventLifecycle(ctor: typeof ReactiveElement): void {\n if ((ctor as unknown as Record<symbol, boolean>)[MODEL_EVENT_PATCHED]) {\n return;\n }\n (ctor as unknown as Record<symbol, boolean>)[MODEL_EVENT_PATCHED] = true;\n\n const originalConnected = ctor.prototype.connectedCallback;\n const originalDisconnected = ctor.prototype.disconnectedCallback;\n\n ctor.prototype.connectedCallback = function connectedCallback(\n this: LitElement & Record<symbol, Map<string, { listener: (e: CustomEvent) => void; field: FieldNodeLike; eventType: string }>>\n ) {\n originalConnected?.call(this);\n\n const methods = (this.constructor as unknown as Record<symbol, EventBindingMeta[]>)[MODEL_EVENT_METHODS];\n if (!methods) return;\n\n const listeners = new Map<string, { listener: (e: CustomEvent) => void; field: FieldNodeLike; eventType: string }>();\n this[MODEL_EVENT_LISTENERS] = listeners;\n\n methods.forEach(({ propertyKey, model, path, eventType, method }) => {\n // If path is specified, listen on that field; otherwise listen on root model\n const field = path ? getFieldForPath(model, path) : model;\n\n const listener = (e: CustomEvent) => {\n method.call(this, e.detail);\n };\n\n listeners.set(propertyKey, { listener, field, eventType });\n field.__addEventListener(eventType, listener);\n });\n };\n\n ctor.prototype.disconnectedCallback = function disconnectedCallback(\n this: LitElement & Record<symbol, Map<string, { listener: (e: CustomEvent) => void; field: FieldNodeLike; eventType: string }>>\n ) {\n const listeners = this[MODEL_EVENT_LISTENERS];\n if (listeners) {\n listeners.forEach(({ listener, field, eventType }) => {\n field.__removeEventListener(eventType, listener);\n });\n listeners.clear();\n }\n\n originalDisconnected?.call(this);\n };\n}\n"]}
|
|
1
|
+
{"version":3,"file":"ModelDecorators.js","sourceRoot":"","sources":["../../src/decorators/ModelDecorators.ts"],"names":[],"mappings":"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","sourcesContent":["/* eslint-disable no-param-reassign */\nimport { LitElement, ReactiveElement } from \"lit\";\nimport type { ModelEventType } from '@/FieldNode';\n\n\n\n/**\n * Event map for FieldNode model events.\n * Most events don't have detail - they just notify that something changed.\n *\n * This may look like a copy of the ModelEventType, but is needed for the implementation.\n */\nexport interface ModelEventMap {\n update: undefined;\n \"field-value-changed\": unknown;\n \"this-field-value-changed\": undefined;\n \"field-value-updated\": unknown;\n \"this-state-changed\": undefined;\n \"state-changed\": unknown;\n \"validity-changed\": undefined;\n \"array-changed\": unknown;\n \"this-array-changed\": undefined;\n \"map-changed\": unknown;\n \"this-map-changed\": undefined;\n \"parent-readonly-set\": undefined;\n \"parent-readonly-unset\": undefined;\n \"model-injected\": undefined;\n}\n\n/**\n * Interface for FieldNode-like objects that support event listening and path navigation.\n */\ninterface FieldNodeLike {\n __addEventListener(type: string, listener: (e: CustomEvent) => void): void;\n __removeEventListener(type: string, listener: (e: CustomEvent) => void): void;\n __getFieldNodeByPath?(path: string): FieldNodeLike | undefined;\n value?: unknown;\n}\n\n// ─────────────────────────────────────────────────────────────────\n// Metadata Storage\n// ─────────────────────────────────────────────────────────────────\n\ninterface BindingMeta {\n model: FieldNodeLike;\n path: string;\n eventType: ModelEventType;\n}\nconst bindingsMetadata = new WeakMap<object, Map<string, BindingMeta>>();\n\ninterface EventBindingMeta {\n propertyKey: string;\n model: FieldNodeLike;\n path: string | null;\n eventType: ModelEventType;\n // eslint-disable-next-line @typescript-eslint/no-unsafe-function-type, @typescript-eslint/ban-types\n method: Function;\n}\n\n// Symbol keys for instance storage\nconst MODEL_BIND_LISTENERS = Symbol.for(\"__modelBindListeners__\");\nconst MODEL_EVENT_LISTENERS = Symbol.for(\"__modelEventListeners__\");\nconst MODEL_BIND_PATCHED = Symbol.for(\"__modelBindPatched__\");\nconst MODEL_EVENT_PATCHED = Symbol.for(\"__modelEventPatched__\");\nconst MODEL_EVENT_METHODS = Symbol.for(\"__modelEventMethods__\");\n\n// ─────────────────────────────────────────────────────────────────\n// ModelBindings Factory\n// ─────────────────────────────────────────────────────────────────\n\n/**\n * ### ModelBindings Factory\n *\n * Creates type-safe decorators bound to a specific FieldNode model.\n * Use this to bind component properties and methods to model events.\n *\n * Usage:\n * ```typescript\n * import { ModelBindings } from \"@x/furo/open-models/ModelDecorators\";\n * import { CubeEntityModel } from \"./CubeEntityModel\";\n *\n * const cubeModel = ModelBindings(CubeEntityModel.model);\n *\n * class MyComponent extends LitElement {\n * // Bind to a nested field value - updates when cube.length changes\n * @cubeModel.bind(\"cube.length\")\n * @state()\n * private cubeLength: number = 0;\n *\n * // Bind to model validity\n * @cubeModel.bind(\"__isValid\", \"validity-changed\")\n * @state()\n * private isValid: boolean = true;\n *\n * // React to any field value change on the model\n * @cubeModel.onEvent(\"field-value-changed\")\n * private onAnyFieldChanged() {\n * console.log(\"Something changed!\");\n * }\n *\n * // React to a specific field's changes\n * @cubeModel.onFieldEvent(\"cube.length\", \"this-field-value-changed\")\n * private onLengthChanged() {\n * console.log(\"Length changed!\");\n * }\n * }\n * ```\n *\n * @param model - The FieldNode model to bind to\n * @returns Object with `bind`, `onEvent`, and `onFieldEvent` decorator factories\n */\nexport function ModelBindings<TEventMap extends ModelEventMap = ModelEventMap>(model: FieldNodeLike) {\n return {\n /**\n * Binds a component property to a model field value.\n * When the field changes, the property is automatically updated.\n *\n * @param path - Path to the field (e.g., \"cube.length\", \"__isValid\")\n * @param eventType - Event to listen for (defaults to \"this-field-value-changed\")\n */\n bind(path: string, eventType: ModelEventType = \"this-field-value-changed\") {\n return function bindDecorator(target: object, propertyKey: string) {\n let metadata = bindingsMetadata.get(target);\n if (!metadata) {\n metadata = new Map();\n bindingsMetadata.set(target, metadata);\n }\n metadata.set(propertyKey, { model, path, eventType });\n\n patchBindLifecycle(target.constructor as typeof ReactiveElement);\n };\n },\n\n /**\n * Binds a method to an event on the root model.\n * When the event fires, the method is called.\n *\n * @param eventType - The event type to listen for\n */\n onEvent<K extends keyof TEventMap & ModelEventType>(eventType: K) {\n return function onEventDecorator(target: object, propertyKey: string, descriptor: PropertyDescriptor) {\n const originalMethod = descriptor.value;\n const ctor = target.constructor as typeof ReactiveElement;\n\n let methods = (ctor as unknown as Record<symbol, EventBindingMeta[]>)[MODEL_EVENT_METHODS];\n if (!methods) {\n methods = [];\n (ctor as unknown as Record<symbol, EventBindingMeta[]>)[MODEL_EVENT_METHODS] = methods;\n }\n methods.push({ propertyKey, model, path: null, eventType, method: originalMethod });\n\n patchEventLifecycle(ctor);\n };\n },\n\n /**\n * Binds a method to an event on a specific field.\n * When the event fires on that field, the method is called.\n *\n * @param path - Path to the field (e.g., \"cube.length\")\n * @param eventType - The event type to listen for\n */\n onFieldEvent<K extends keyof TEventMap & ModelEventType>(path: string, eventType: K) {\n return function onFieldEventDecorator(target: object, propertyKey: string, descriptor: PropertyDescriptor) {\n const originalMethod = descriptor.value;\n const ctor = target.constructor as typeof ReactiveElement;\n\n let methods = (ctor as unknown as Record<symbol, EventBindingMeta[]>)[MODEL_EVENT_METHODS];\n if (!methods) {\n methods = [];\n (ctor as unknown as Record<symbol, EventBindingMeta[]>)[MODEL_EVENT_METHODS] = methods;\n }\n methods.push({ propertyKey, model, path, eventType, method: originalMethod });\n\n patchEventLifecycle(ctor);\n };\n },\n };\n}\n\n// ─────────────────────────────────────────────────────────────────\n// Lifecycle Patching\n// ─────────────────────────────────────────────────────────────────\n\n/**\n * Get the field node for a path, handling both direct properties and nested paths.\n */\nfunction getFieldForPath(model: FieldNodeLike, path: string): FieldNodeLike {\n // Check if it's a direct property (starts with __ or no dots)\n if (path.startsWith(\"__\") || !path.includes(\".\")) {\n return model;\n }\n // Navigate to nested field (we trust the field exists per user guarantee)\n if (model.__getFieldNodeByPath) {\n return model.__getFieldNodeByPath(path) as FieldNodeLike;\n }\n return model;\n}\n\n/**\n * Get the value for a path from the model.\n */\nfunction getValueForPath(model: FieldNodeLike, path: string): unknown {\n if (path.startsWith(\"__\")) {\n // Direct property access for internal properties\n return (model as unknown as Record<string, unknown>)[path];\n }\n if (!path.includes(\".\")) {\n // Direct child field\n const field = (model as unknown as Record<string, unknown>)[path] as FieldNodeLike | undefined;\n return field?.value ?? field;\n }\n // Nested path - get the field and return its value\n if (model.__getFieldNodeByPath) {\n const field = model.__getFieldNodeByPath(path);\n return field?.value ?? field;\n }\n return undefined;\n}\n\n/**\n * Patch connectedCallback/disconnectedCallback for bind decorators.\n */\nfunction patchBindLifecycle(ctor: typeof ReactiveElement): void {\n if ((ctor as unknown as Record<symbol, boolean>)[MODEL_BIND_PATCHED]) {\n return;\n }\n (ctor as unknown as Record<symbol, boolean>)[MODEL_BIND_PATCHED] = true;\n\n const originalConnected = ctor.prototype.connectedCallback;\n const originalDisconnected = ctor.prototype.disconnectedCallback;\n\n ctor.prototype.connectedCallback = function connectedCallback(\n this: LitElement & Record<symbol, Map<string, { listener: (e: CustomEvent) => void; field: FieldNodeLike; eventType: string }>>\n ) {\n originalConnected?.call(this);\n\n const metadata = bindingsMetadata.get(Object.getPrototypeOf(this));\n if (!metadata) return;\n\n const listeners = new Map<string, { listener: (e: CustomEvent) => void; field: FieldNodeLike; eventType: string }>();\n this[MODEL_BIND_LISTENERS] = listeners;\n\n metadata.forEach(({ model, path, eventType }, propKey) => {\n const field = getFieldForPath(model, path);\n\n // Set initial value\n (this as unknown as Record<string, unknown>)[propKey] = getValueForPath(model, path);\n\n const listener = () => {\n (this as unknown as Record<string, unknown>)[propKey] = getValueForPath(model, path);\n };\n\n listeners.set(propKey, { listener, field, eventType });\n field.__addEventListener(eventType, listener);\n });\n };\n\n ctor.prototype.disconnectedCallback = function disconnectedCallback(\n this: LitElement & Record<symbol, Map<string, { listener: (e: CustomEvent) => void; field: FieldNodeLike; eventType: string }>>\n ) {\n const listeners = this[MODEL_BIND_LISTENERS];\n if (listeners) {\n listeners.forEach(({ listener, field, eventType }) => {\n field.__removeEventListener(eventType, listener);\n });\n listeners.clear();\n }\n\n originalDisconnected?.call(this);\n };\n}\n\n/**\n * Patch connectedCallback/disconnectedCallback for event decorators.\n */\nfunction patchEventLifecycle(ctor: typeof ReactiveElement): void {\n if ((ctor as unknown as Record<symbol, boolean>)[MODEL_EVENT_PATCHED]) {\n return;\n }\n (ctor as unknown as Record<symbol, boolean>)[MODEL_EVENT_PATCHED] = true;\n\n const originalConnected = ctor.prototype.connectedCallback;\n const originalDisconnected = ctor.prototype.disconnectedCallback;\n\n ctor.prototype.connectedCallback = function connectedCallback(\n this: LitElement & Record<symbol, Map<string, { listener: (e: CustomEvent) => void; field: FieldNodeLike; eventType: string }>>\n ) {\n originalConnected?.call(this);\n\n const methods = (this.constructor as unknown as Record<symbol, EventBindingMeta[]>)[MODEL_EVENT_METHODS];\n if (!methods) return;\n\n const listeners = new Map<string, { listener: (e: CustomEvent) => void; field: FieldNodeLike; eventType: string }>();\n this[MODEL_EVENT_LISTENERS] = listeners;\n\n methods.forEach(({ propertyKey, model, path, eventType, method }) => {\n // If path is specified, listen on that field; otherwise listen on root model\n const field = path ? getFieldForPath(model, path) : model;\n\n const listener = (e: CustomEvent) => {\n method.call(this, e.detail);\n };\n\n listeners.set(propertyKey, { listener, field, eventType });\n field.__addEventListener(eventType, listener);\n });\n };\n\n ctor.prototype.disconnectedCallback = function disconnectedCallback(\n this: LitElement & Record<symbol, Map<string, { listener: (e: CustomEvent) => void; field: FieldNodeLike; eventType: string }>>\n ) {\n const listeners = this[MODEL_EVENT_LISTENERS];\n if (listeners) {\n listeners.forEach(({ listener, field, eventType }) => {\n field.__removeEventListener(eventType, listener);\n });\n listeners.clear();\n }\n\n originalDisconnected?.call(this);\n };\n}\n"]}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { EntityServiceEventMap } from "./EntityServiceTypes.js";
|
|
2
2
|
/**
|
|
3
|
-
* ###
|
|
3
|
+
* ### ServiceBindings Factory
|
|
4
4
|
*
|
|
5
5
|
* Creates type-safe decorators bound to a specific service instance.
|
|
6
6
|
* Use this to bind component properties and methods to service events.
|
|
@@ -12,9 +12,9 @@ import { EntityServiceEventMap } from "./EntityServiceTypes.js";
|
|
|
12
12
|
* Usage:
|
|
13
13
|
* ```typescript
|
|
14
14
|
* import { cubeEntityService } from "./CubeEntityService";
|
|
15
|
-
* import {
|
|
15
|
+
* import { ServiceBindings } from "./ServiceDecorators.js";
|
|
16
16
|
*
|
|
17
|
-
* const cube =
|
|
17
|
+
* const cube = ServiceBindings(cubeEntityService);
|
|
18
18
|
*
|
|
19
19
|
* class MyComponent extends LitElement {
|
|
20
20
|
* // Property binding - type-safe event name, auto-extracts from detail
|
|
@@ -46,7 +46,7 @@ import { EntityServiceEventMap } from "./EntityServiceTypes.js";
|
|
|
46
46
|
* "custom-event": { data: string };
|
|
47
47
|
* }
|
|
48
48
|
*
|
|
49
|
-
* const myBindings =
|
|
49
|
+
* const myBindings = ServiceBindings<MyServiceEventMap>(myService);
|
|
50
50
|
* ```
|
|
51
51
|
*
|
|
52
52
|
* @typeParam TEventMap - The event map type (defaults to EntityServiceEventMap)
|
|
@@ -6,7 +6,7 @@ const PROPERTY_PATCHED = Symbol.for("__servicePropertyPatched__");
|
|
|
6
6
|
const EVENT_PATCHED = Symbol.for("__serviceEventPatched__");
|
|
7
7
|
const EVENT_METHODS = Symbol.for("__serviceEventMethods__");
|
|
8
8
|
/**
|
|
9
|
-
* ###
|
|
9
|
+
* ### ServiceBindings Factory
|
|
10
10
|
*
|
|
11
11
|
* Creates type-safe decorators bound to a specific service instance.
|
|
12
12
|
* Use this to bind component properties and methods to service events.
|
|
@@ -18,9 +18,9 @@ const EVENT_METHODS = Symbol.for("__serviceEventMethods__");
|
|
|
18
18
|
* Usage:
|
|
19
19
|
* ```typescript
|
|
20
20
|
* import { cubeEntityService } from "./CubeEntityService";
|
|
21
|
-
* import {
|
|
21
|
+
* import { ServiceBindings } from "./ServiceDecorators.js";
|
|
22
22
|
*
|
|
23
|
-
* const cube =
|
|
23
|
+
* const cube = ServiceBindings(cubeEntityService);
|
|
24
24
|
*
|
|
25
25
|
* class MyComponent extends LitElement {
|
|
26
26
|
* // Property binding - type-safe event name, auto-extracts from detail
|
|
@@ -52,7 +52,7 @@ const EVENT_METHODS = Symbol.for("__serviceEventMethods__");
|
|
|
52
52
|
* "custom-event": { data: string };
|
|
53
53
|
* }
|
|
54
54
|
*
|
|
55
|
-
* const myBindings =
|
|
55
|
+
* const myBindings = ServiceBindings<MyServiceEventMap>(myService);
|
|
56
56
|
* ```
|
|
57
57
|
*
|
|
58
58
|
* @typeParam TEventMap - The event map type (defaults to EntityServiceEventMap)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ServiceDecorators.js","sourceRoot":"","sources":["../../src/decorators/ServiceDecorators.ts"],"names":[],"mappings":"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","sourcesContent":["/* eslint-disable no-param-reassign */\nimport { LitElement, ReactiveElement } from \"lit\";\n\nimport { EntityServiceEventMap } from \"./EntityServiceTypes\";\n\n/**\n * Metadata storage for property bindings\n * Maps: class prototype -> Map<propertyKey, { service, eventType, detailKey }>\n */\ninterface PropertyBindingMeta {\n service: EventTarget;\n eventType: string;\n detailKey: string;\n}\nconst propertyBindingsMetadata = new WeakMap<object, Map<string, PropertyBindingMeta>>();\n\n/**\n * Metadata storage for event method bindings\n * Maps: class constructor -> Array<{ propertyKey, service, eventType, method }>\n */\ninterface EventBindingMeta {\n propertyKey: string;\n service: EventTarget;\n eventType: string;\n // eslint-disable-next-line @typescript-eslint/no-unsafe-function-type\n method: Function;\n}\n\n// Symbol keys for instance storage\nconst PROPERTY_LISTENERS = Symbol.for(\"__servicePropertyListeners__\");\nconst EVENT_LISTENERS = Symbol.for(\"__serviceEventListeners__\");\nconst PROPERTY_PATCHED = Symbol.for(\"__servicePropertyPatched__\");\nconst EVENT_PATCHED = Symbol.for(\"__serviceEventPatched__\");\nconst EVENT_METHODS = Symbol.for(\"__serviceEventMethods__\");\n\n/**\n * ### serviceBindings Factory\n *\n * Creates type-safe decorators bound to a specific service instance.\n * Use this to bind component properties and methods to service events.\n *\n * The factory is generic and works with any `EventTarget`.\n * Event types and their detail payloads are type-checked at compile time\n * via the `TEventMap` type parameter.\n *\n * Usage:\n * ```typescript\n * import { cubeEntityService } from \"./CubeEntityService\";\n * import { serviceBindings } from \"./ServiceDecorators\";\n *\n * const cube = serviceBindings(cubeEntityService);\n *\n * class MyComponent extends LitElement {\n * // Property binding - type-safe event name, auto-extracts from detail\n * @cube.bindToEvent(\"busy-changed\")\n * @state()\n * private busy: boolean = false;\n *\n * // Event binding - type-safe event name and detail type\n * @cube.onEvent(\"response-received\")\n * private onResponseReceived() {\n * console.log(\"Data received!\");\n * }\n *\n * @cube.onEvent(\"error-5xx\")\n * private onError(detail: { serverResponse: Response }) {\n * console.error(\"Server error:\", detail.serverResponse);\n * }\n *\n * // Compile error! \"typo-event\" is not a valid event type\n * // @cube.onEvent(\"typo-event\")\n * }\n * ```\n *\n * ### Custom Event Maps\n *\n * To add custom events, extend the `EntityServiceEventMap`:\n * ```typescript\n * interface MyServiceEventMap extends EntityServiceEventMap {\n * \"custom-event\": { data: string };\n * }\n *\n * const myBindings = serviceBindings<MyServiceEventMap>(myService);\n * ```\n *\n * @typeParam TEventMap - The event map type (defaults to EntityServiceEventMap)\n * @param service - The EventTarget service to bind to\n * @returns Object with `bindToEvent` and `onEvent` decorator factories\n */\nexport function ServiceBindings<TEventMap extends EntityServiceEventMap = EntityServiceEventMap>(service: EventTarget) {\n return {\n /**\n * Binds a property to a service event.\n * When the event fires, the property is automatically updated from event.detail.\n *\n * @typeParam K - The event type (constrained to valid event names)\n * @param eventType - The event name to listen for\n * @param detailKey - Optional key to extract from event.detail (defaults to inferring from event type)\n */\n bindToEvent<K extends keyof TEventMap & string>(eventType: K, detailKey?: string) {\n return function bindToEventDecorator(target: object, propertyKey: string) {\n // Infer detailKey from event type if not provided\n // e.g., \"busy-changed\" -> \"busy\"\n const key = detailKey ?? inferDetailKey(eventType, propertyKey);\n\n // Get or create metadata map for this class\n let metadata = propertyBindingsMetadata.get(target);\n if (!metadata) {\n metadata = new Map();\n propertyBindingsMetadata.set(target, metadata);\n }\n metadata.set(propertyKey, { service, eventType, detailKey: key });\n\n // Patch lifecycle methods (only once per class)\n patchPropertyLifecycle(target.constructor as typeof ReactiveElement);\n };\n },\n\n /**\n * Binds a method to a service event.\n * When the event fires, the method is called with event.detail as argument.\n *\n * The detail type is inferred from the event map:\n * - `@cube.onEvent(\"busy-changed\")` → method receives `{ busy: boolean }`\n * - `@cube.onEvent(\"error-5xx\")` → method receives `{ serverResponse: Response }`\n * - `@cube.onEvent(\"response-received\")` → method receives `{ response, serverResponse }`\n *\n * @typeParam K - The event type (constrained to valid event names)\n * @param eventType - The event name to listen for\n */\n onEvent<K extends keyof TEventMap & string>(eventType: K) {\n return function onEventDecorator(target: object, propertyKey: string, descriptor: PropertyDescriptor) {\n const originalMethod = descriptor.value;\n const ctor = target.constructor as typeof ReactiveElement;\n\n // Store method metadata on the constructor\n let methods = (ctor as unknown as Record<symbol, EventBindingMeta[]>)[EVENT_METHODS];\n if (!methods) {\n methods = [];\n (ctor as unknown as Record<symbol, EventBindingMeta[]>)[EVENT_METHODS] = methods;\n }\n methods.push({ propertyKey, service, eventType, method: originalMethod });\n\n // Patch lifecycle methods (only once per class)\n patchEventLifecycle(ctor);\n };\n },\n };\n}\n\n/**\n * Infer the detail key from the event type or property name\n */\nfunction inferDetailKey(eventType: string, propertyKey: string): string {\n // Common patterns: \"busy-changed\" -> \"busy\", \"validity-changed\" -> check property\n const match = eventType.match(/^(.+)-changed$/);\n if (match) {\n return match[1];\n }\n // Fall back to property name\n return propertyKey;\n}\n\n/**\n * Patch connectedCallback/disconnectedCallback for property bindings\n */\nfunction patchPropertyLifecycle(ctor: typeof ReactiveElement): void {\n if ((ctor as unknown as Record<symbol, boolean>)[PROPERTY_PATCHED]) {\n return;\n }\n (ctor as unknown as Record<symbol, boolean>)[PROPERTY_PATCHED] = true;\n\n const originalConnected = ctor.prototype.connectedCallback;\n const originalDisconnected = ctor.prototype.disconnectedCallback;\n\n ctor.prototype.connectedCallback = function connectedCallback(\n this: LitElement & Record<symbol, Map<string, { listener: EventListener; service: EventTarget; eventType: string }>>\n ) {\n originalConnected?.call(this);\n\n const metadata = propertyBindingsMetadata.get(Object.getPrototypeOf(this));\n if (!metadata) return;\n\n const listeners = new Map<string, { listener: EventListener; service: EventTarget; eventType: string }>();\n this[PROPERTY_LISTENERS] = listeners;\n\n metadata.forEach(({ service, eventType, detailKey }, propKey) => {\n const listener = ((e: CustomEvent) => {\n if (e.detail && detailKey in e.detail) {\n (this as unknown as Record<string, unknown>)[propKey] = e.detail[detailKey];\n }\n }) as EventListener;\n\n listeners.set(propKey, { listener, service, eventType });\n service.addEventListener(eventType, listener);\n });\n };\n\n ctor.prototype.disconnectedCallback = function disconnectedCallback(\n this: LitElement & Record<symbol, Map<string, { listener: EventListener; service: EventTarget; eventType: string }>>\n ) {\n const listeners = this[PROPERTY_LISTENERS];\n if (listeners) {\n listeners.forEach(({ listener, service, eventType }) => {\n service.removeEventListener(eventType, listener);\n });\n listeners.clear();\n }\n\n originalDisconnected?.call(this);\n };\n}\n\n/**\n * Patch connectedCallback/disconnectedCallback for event method bindings\n */\nfunction patchEventLifecycle(ctor: typeof ReactiveElement): void {\n if ((ctor as unknown as Record<symbol, boolean>)[EVENT_PATCHED]) {\n return;\n }\n (ctor as unknown as Record<symbol, boolean>)[EVENT_PATCHED] = true;\n\n const originalConnected = ctor.prototype.connectedCallback;\n const originalDisconnected = ctor.prototype.disconnectedCallback;\n\n ctor.prototype.connectedCallback = function connectedCallback(\n this: LitElement & Record<symbol, Map<string, { listener: EventListener; service: EventTarget; eventType: string }>>\n ) {\n originalConnected?.call(this);\n\n const methods = (this.constructor as unknown as Record<symbol, EventBindingMeta[]>)[EVENT_METHODS];\n if (!methods) return;\n\n const listeners = new Map<string, { listener: EventListener; service: EventTarget; eventType: string }>();\n this[EVENT_LISTENERS] = listeners;\n\n methods.forEach(({ propertyKey, service, eventType, method }) => {\n const listener = ((e: CustomEvent) => {\n method.call(this, e.detail);\n }) as EventListener;\n\n listeners.set(propertyKey, { listener, service, eventType });\n service.addEventListener(eventType, listener);\n });\n };\n\n ctor.prototype.disconnectedCallback = function disconnectedCallback(\n this: LitElement & Record<symbol, Map<string, { listener: EventListener; service: EventTarget; eventType: string }>>\n ) {\n const listeners = this[EVENT_LISTENERS];\n if (listeners) {\n listeners.forEach(({ listener, service, eventType }) => {\n service.removeEventListener(eventType, listener);\n });\n listeners.clear();\n }\n\n originalDisconnected?.call(this);\n };\n}\n"]}
|
|
1
|
+
{"version":3,"file":"ServiceDecorators.js","sourceRoot":"","sources":["../../src/decorators/ServiceDecorators.ts"],"names":[],"mappings":"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","sourcesContent":["/* eslint-disable no-param-reassign */\nimport { LitElement, ReactiveElement } from \"lit\";\n\nimport { EntityServiceEventMap } from \"./EntityServiceTypes\";\n\n/**\n * Metadata storage for property bindings\n * Maps: class prototype -> Map<propertyKey, { service, eventType, detailKey }>\n */\ninterface PropertyBindingMeta {\n service: EventTarget;\n eventType: string;\n detailKey: string;\n}\nconst propertyBindingsMetadata = new WeakMap<object, Map<string, PropertyBindingMeta>>();\n\n/**\n * Metadata storage for event method bindings\n * Maps: class constructor -> Array<{ propertyKey, service, eventType, method }>\n */\ninterface EventBindingMeta {\n propertyKey: string;\n service: EventTarget;\n eventType: string;\n // eslint-disable-next-line @typescript-eslint/no-unsafe-function-type\n method: Function;\n}\n\n// Symbol keys for instance storage\nconst PROPERTY_LISTENERS = Symbol.for(\"__servicePropertyListeners__\");\nconst EVENT_LISTENERS = Symbol.for(\"__serviceEventListeners__\");\nconst PROPERTY_PATCHED = Symbol.for(\"__servicePropertyPatched__\");\nconst EVENT_PATCHED = Symbol.for(\"__serviceEventPatched__\");\nconst EVENT_METHODS = Symbol.for(\"__serviceEventMethods__\");\n\n/**\n * ### ServiceBindings Factory\n *\n * Creates type-safe decorators bound to a specific service instance.\n * Use this to bind component properties and methods to service events.\n *\n * The factory is generic and works with any `EventTarget`.\n * Event types and their detail payloads are type-checked at compile time\n * via the `TEventMap` type parameter.\n *\n * Usage:\n * ```typescript\n * import { cubeEntityService } from \"./CubeEntityService\";\n * import { ServiceBindings } from \"./ServiceDecorators\";\n *\n * const cube = ServiceBindings(cubeEntityService);\n *\n * class MyComponent extends LitElement {\n * // Property binding - type-safe event name, auto-extracts from detail\n * @cube.bindToEvent(\"busy-changed\")\n * @state()\n * private busy: boolean = false;\n *\n * // Event binding - type-safe event name and detail type\n * @cube.onEvent(\"response-received\")\n * private onResponseReceived() {\n * console.log(\"Data received!\");\n * }\n *\n * @cube.onEvent(\"error-5xx\")\n * private onError(detail: { serverResponse: Response }) {\n * console.error(\"Server error:\", detail.serverResponse);\n * }\n *\n * // Compile error! \"typo-event\" is not a valid event type\n * // @cube.onEvent(\"typo-event\")\n * }\n * ```\n *\n * ### Custom Event Maps\n *\n * To add custom events, extend the `EntityServiceEventMap`:\n * ```typescript\n * interface MyServiceEventMap extends EntityServiceEventMap {\n * \"custom-event\": { data: string };\n * }\n *\n * const myBindings = ServiceBindings<MyServiceEventMap>(myService);\n * ```\n *\n * @typeParam TEventMap - The event map type (defaults to EntityServiceEventMap)\n * @param service - The EventTarget service to bind to\n * @returns Object with `bindToEvent` and `onEvent` decorator factories\n */\nexport function ServiceBindings<TEventMap extends EntityServiceEventMap = EntityServiceEventMap>(service: EventTarget) {\n return {\n /**\n * Binds a property to a service event.\n * When the event fires, the property is automatically updated from event.detail.\n *\n * @typeParam K - The event type (constrained to valid event names)\n * @param eventType - The event name to listen for\n * @param detailKey - Optional key to extract from event.detail (defaults to inferring from event type)\n */\n bindToEvent<K extends keyof TEventMap & string>(eventType: K, detailKey?: string) {\n return function bindToEventDecorator(target: object, propertyKey: string) {\n // Infer detailKey from event type if not provided\n // e.g., \"busy-changed\" -> \"busy\"\n const key = detailKey ?? inferDetailKey(eventType, propertyKey);\n\n // Get or create metadata map for this class\n let metadata = propertyBindingsMetadata.get(target);\n if (!metadata) {\n metadata = new Map();\n propertyBindingsMetadata.set(target, metadata);\n }\n metadata.set(propertyKey, { service, eventType, detailKey: key });\n\n // Patch lifecycle methods (only once per class)\n patchPropertyLifecycle(target.constructor as typeof ReactiveElement);\n };\n },\n\n /**\n * Binds a method to a service event.\n * When the event fires, the method is called with event.detail as argument.\n *\n * The detail type is inferred from the event map:\n * - `@cube.onEvent(\"busy-changed\")` → method receives `{ busy: boolean }`\n * - `@cube.onEvent(\"error-5xx\")` → method receives `{ serverResponse: Response }`\n * - `@cube.onEvent(\"response-received\")` → method receives `{ response, serverResponse }`\n *\n * @typeParam K - The event type (constrained to valid event names)\n * @param eventType - The event name to listen for\n */\n onEvent<K extends keyof TEventMap & string>(eventType: K) {\n return function onEventDecorator(target: object, propertyKey: string, descriptor: PropertyDescriptor) {\n const originalMethod = descriptor.value;\n const ctor = target.constructor as typeof ReactiveElement;\n\n // Store method metadata on the constructor\n let methods = (ctor as unknown as Record<symbol, EventBindingMeta[]>)[EVENT_METHODS];\n if (!methods) {\n methods = [];\n (ctor as unknown as Record<symbol, EventBindingMeta[]>)[EVENT_METHODS] = methods;\n }\n methods.push({ propertyKey, service, eventType, method: originalMethod });\n\n // Patch lifecycle methods (only once per class)\n patchEventLifecycle(ctor);\n };\n },\n };\n}\n\n/**\n * Infer the detail key from the event type or property name\n */\nfunction inferDetailKey(eventType: string, propertyKey: string): string {\n // Common patterns: \"busy-changed\" -> \"busy\", \"validity-changed\" -> check property\n const match = eventType.match(/^(.+)-changed$/);\n if (match) {\n return match[1];\n }\n // Fall back to property name\n return propertyKey;\n}\n\n/**\n * Patch connectedCallback/disconnectedCallback for property bindings\n */\nfunction patchPropertyLifecycle(ctor: typeof ReactiveElement): void {\n if ((ctor as unknown as Record<symbol, boolean>)[PROPERTY_PATCHED]) {\n return;\n }\n (ctor as unknown as Record<symbol, boolean>)[PROPERTY_PATCHED] = true;\n\n const originalConnected = ctor.prototype.connectedCallback;\n const originalDisconnected = ctor.prototype.disconnectedCallback;\n\n ctor.prototype.connectedCallback = function connectedCallback(\n this: LitElement & Record<symbol, Map<string, { listener: EventListener; service: EventTarget; eventType: string }>>\n ) {\n originalConnected?.call(this);\n\n const metadata = propertyBindingsMetadata.get(Object.getPrototypeOf(this));\n if (!metadata) return;\n\n const listeners = new Map<string, { listener: EventListener; service: EventTarget; eventType: string }>();\n this[PROPERTY_LISTENERS] = listeners;\n\n metadata.forEach(({ service, eventType, detailKey }, propKey) => {\n const listener = ((e: CustomEvent) => {\n if (e.detail && detailKey in e.detail) {\n (this as unknown as Record<string, unknown>)[propKey] = e.detail[detailKey];\n }\n }) as EventListener;\n\n listeners.set(propKey, { listener, service, eventType });\n service.addEventListener(eventType, listener);\n });\n };\n\n ctor.prototype.disconnectedCallback = function disconnectedCallback(\n this: LitElement & Record<symbol, Map<string, { listener: EventListener; service: EventTarget; eventType: string }>>\n ) {\n const listeners = this[PROPERTY_LISTENERS];\n if (listeners) {\n listeners.forEach(({ listener, service, eventType }) => {\n service.removeEventListener(eventType, listener);\n });\n listeners.clear();\n }\n\n originalDisconnected?.call(this);\n };\n}\n\n/**\n * Patch connectedCallback/disconnectedCallback for event method bindings\n */\nfunction patchEventLifecycle(ctor: typeof ReactiveElement): void {\n if ((ctor as unknown as Record<symbol, boolean>)[EVENT_PATCHED]) {\n return;\n }\n (ctor as unknown as Record<symbol, boolean>)[EVENT_PATCHED] = true;\n\n const originalConnected = ctor.prototype.connectedCallback;\n const originalDisconnected = ctor.prototype.disconnectedCallback;\n\n ctor.prototype.connectedCallback = function connectedCallback(\n this: LitElement & Record<symbol, Map<string, { listener: EventListener; service: EventTarget; eventType: string }>>\n ) {\n originalConnected?.call(this);\n\n const methods = (this.constructor as unknown as Record<symbol, EventBindingMeta[]>)[EVENT_METHODS];\n if (!methods) return;\n\n const listeners = new Map<string, { listener: EventListener; service: EventTarget; eventType: string }>();\n this[EVENT_LISTENERS] = listeners;\n\n methods.forEach(({ propertyKey, service, eventType, method }) => {\n const listener = ((e: CustomEvent) => {\n method.call(this, e.detail);\n }) as EventListener;\n\n listeners.set(propertyKey, { listener, service, eventType });\n service.addEventListener(eventType, listener);\n });\n };\n\n ctor.prototype.disconnectedCallback = function disconnectedCallback(\n this: LitElement & Record<symbol, Map<string, { listener: EventListener; service: EventTarget; eventType: string }>>\n ) {\n const listeners = this[EVENT_LISTENERS];\n if (listeners) {\n listeners.forEach(({ listener, service, eventType }) => {\n service.removeEventListener(eventType, listener);\n });\n listeners.clear();\n }\n\n originalDisconnected?.call(this);\n };\n}\n"]}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { FieldNode, ValueStateSummary } from './FieldNode.js';
|
|
1
|
+
export { FieldNode, ValueStateSummary, type ModelEventType } from './FieldNode.js';
|
|
2
2
|
export { Registry } from './Registry.js';
|
|
3
3
|
export { ValueState } from './ValueState.js';
|
|
4
4
|
export { OPEN_MODELS_OPTIONS } from './OPEN_MODELS_OPTIONS.js';
|
|
@@ -38,7 +38,6 @@ export { MAP } from './proxies/MAP.js';
|
|
|
38
38
|
export { RECURSION } from './proxies/RECURSION.js';
|
|
39
39
|
export { ServiceBindings } from './decorators/ServiceDecorators.js';
|
|
40
40
|
export { ModelBindings } from './decorators/ModelDecorators.js';
|
|
41
|
-
export type { ModelEventType } from './decorators/ModelDecorators.js';
|
|
42
41
|
export { fieldBindings } from './decorators/FieldBindings.js';
|
|
43
42
|
export type { BindableComponent, FieldNodeLike } from './decorators/FieldBindings.js';
|
|
44
43
|
export { SchemaBuilder } from './decorators/SchemaBuilder.js';
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAA0C,MAAM,aAAa,CAAC;AAChF,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AACtC,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1C,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAC5D,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAGvD,aAAa;AACb,OAAO,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAC;AAC/C,OAAO,EAAE,IAAI,EAAE,MAAM,mBAAmB,CAAC;AACzC,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAC3C,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAC3C,OAAO,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAC7C,OAAO,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAC7C,OAAO,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAC7C,OAAO,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAC7C,OAAO,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAC7C,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAC3C,OAAO,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAC7C,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAE3C,aAAa;AACb,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAC3C,OAAO,EAAE,GAAG,EAAE,MAAM,kBAAkB,CAAC;AACvC,OAAO,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AACrD,OAAO,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AACrD,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AACvD,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AACvD,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AACvD,OAAO,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AACrD,OAAO,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AACnD,OAAO,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AACrD,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AACvD,OAAO,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AACnD,OAAO,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAI7C,OAAO,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AACjD,OAAO,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AAEnD,UAAU;AACV,OAAO,EAAE,KAAK,EAAE,MAAM,iBAAiB,CAAC;AACxC,OAAO,EAAE,GAAG,EAAE,MAAM,eAAe,CAAC;AACpC,OAAO,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAEhD,aAAa;AACb,OAAO,EAAE,eAAe,EAAE,MAAM,gCAAgC,CAAC;AACjE,OAAO,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAC;AAC7D,OAAO,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAE3D,OAAO,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAC3D,OAAO,EAAE,2BAA2B,EAAE,cAAc,EAAE,MAAM,0CAA0C,CAAC","sourcesContent":["export { FieldNode, ValueStateSummary, type ModelEventType } from './FieldNode';\nexport { Registry } from './Registry';\nexport { ValueState } from './ValueState';\nexport { OPEN_MODELS_OPTIONS } from './OPEN_MODELS_OPTIONS';\nexport { ToString, ValueOf } from './CustomPrototypes';\nexport { FieldConstraints } from './FieldConstraints';\n\n// Primitives\nexport { BOOLEAN } from './primitives/BOOLEAN';\nexport { ENUM } from './primitives/ENUM';\nexport { INT32 } from './primitives/INT32';\nexport { INT64 } from './primitives/INT64';\nexport { SINT32 } from './primitives/SINT32';\nexport { SINT64 } from './primitives/SINT64';\nexport { UINT32 } from './primitives/UINT32';\nexport { UINT64 } from './primitives/UINT64';\nexport { STRING } from './primitives/STRING';\nexport { BYTES } from './primitives/BYTES';\nexport { DOUBLE } from './primitives/DOUBLE';\nexport { FLOAT } from './primitives/FLOAT';\n\n// well known\nexport { EMPTY } from './well_known/EMPTY';\nexport { ANY } from './well_known/ANY';\nexport { Int32Value } from './well_known/Int32Value';\nexport { Int64Value } from './well_known/Int64Value';\nexport { UInt32Value } from './well_known/UInt32Value';\nexport { UInt64Value } from './well_known/UInt64Value';\nexport { DoubleValue } from './well_known/DoubleValue';\nexport { FloatValue } from './well_known/FloatValue';\nexport { BoolValue } from './well_known/BoolValue';\nexport { BytesValue } from './well_known/BytesValue';\nexport { StringValue } from './well_known/StringValue';\nexport { Timestamp } from './well_known/Timestamp';\nexport { Struct } from './well_known/Struct';\n\nexport { JSONValue } from './well_known/Struct';\nexport { JSONObject } from './well_known/Struct';\nexport { Duration } from './well_known/Duration';\nexport { FieldMask } from './well_known/FieldMask';\n\n// proxies\nexport { ARRAY } from './proxies/ARRAY';\nexport { MAP } from './proxies/MAP';\nexport { RECURSION } from './proxies/RECURSION';\n\n// Decorators\nexport { ServiceBindings } from './decorators/ServiceDecorators';\nexport { ModelBindings } from './decorators/ModelDecorators';\nexport { fieldBindings } from './decorators/FieldBindings';\nexport type { BindableComponent, FieldNodeLike } from './decorators/FieldBindings';\nexport { SchemaBuilder } from './decorators/SchemaBuilder';\nexport { DefaultServiceEventHandlers, CreateDispatch } from './decorators/DefaultServiceEventHandlers';\nexport type { EntityServiceEventType, TypedEntityService } from './decorators/EntityServiceTypes';\nexport type { EntityServiceEventMap } from './decorators/EntityServiceTypes';\n\nexport interface IAny {\n '@type': string;\n [key: string]: unknown;\n}\n"]}
|
package/package.json
CHANGED
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
"url": "git+ssh://git@github.com/eclipse/eclipsefuro-web.git"
|
|
9
9
|
},
|
|
10
10
|
"author": "eclipse furo",
|
|
11
|
-
"version": "1.15.
|
|
11
|
+
"version": "1.15.3",
|
|
12
12
|
"type": "module",
|
|
13
13
|
"main": "dist/index.js",
|
|
14
14
|
"module": "dist/index.js",
|
|
@@ -45,6 +45,10 @@
|
|
|
45
45
|
"custom-elements.json",
|
|
46
46
|
"web-types.json"
|
|
47
47
|
],
|
|
48
|
+
"dependencies": {
|
|
49
|
+
"@types/json-schema": "^7.0.15",
|
|
50
|
+
"json-schema": "^0.4.0"
|
|
51
|
+
},
|
|
48
52
|
"devDependencies": {
|
|
49
53
|
"@bufbuild/buf": "^1.38.0",
|
|
50
54
|
"@bufbuild/protobuf": "^2.0.0",
|
/package/dist/decorators/{defaultServiceEventHandlers.d.ts → DefaultServiceEventHandlers.d.ts}
RENAMED
|
File without changes
|
|
File without changes
|
/package/dist/decorators/{defaultServiceEventHandlers.js.map → DefaultServiceEventHandlers.js.map}
RENAMED
|
File without changes
|