sygnal 2.7.0 → 2.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs.js +97 -33
- package/dist/index.esm.js +97 -33
- package/dist/jsx.cjs.js +1 -1
- package/dist/jsx.esm.js +1 -1
- package/dist/sygnal.min.js +1 -1
- package/package.json +1 -1
package/dist/index.cjs.js
CHANGED
|
@@ -3186,6 +3186,9 @@ function component (opts) {
|
|
|
3186
3186
|
returnFunction = currySources ? (sources) => (new Component({ ...opts, sources })).sinks : (new Component(opts)).sinks;
|
|
3187
3187
|
}
|
|
3188
3188
|
|
|
3189
|
+
returnFunction.componentName = name;
|
|
3190
|
+
returnFunction.isSygnalComponent = true;
|
|
3191
|
+
|
|
3189
3192
|
return returnFunction
|
|
3190
3193
|
}
|
|
3191
3194
|
|
|
@@ -3200,6 +3203,7 @@ class Component {
|
|
|
3200
3203
|
// intent
|
|
3201
3204
|
// request
|
|
3202
3205
|
// model
|
|
3206
|
+
// context
|
|
3203
3207
|
// response
|
|
3204
3208
|
// view
|
|
3205
3209
|
// children
|
|
@@ -3217,14 +3221,17 @@ class Component {
|
|
|
3217
3221
|
// intent$
|
|
3218
3222
|
// action$
|
|
3219
3223
|
// model$
|
|
3224
|
+
// context$
|
|
3220
3225
|
// response$
|
|
3221
3226
|
// sendResponse$
|
|
3222
3227
|
// children$
|
|
3223
3228
|
// vdom$
|
|
3229
|
+
// currentState
|
|
3230
|
+
// currentContext
|
|
3224
3231
|
// subComponentSink$
|
|
3225
3232
|
// unmountRequest$
|
|
3226
3233
|
// unmount()
|
|
3227
|
-
//
|
|
3234
|
+
// _debug
|
|
3228
3235
|
|
|
3229
3236
|
// [ INSTANTIATED STREAM OPERATOR ]
|
|
3230
3237
|
// log
|
|
@@ -3232,7 +3239,7 @@ class Component {
|
|
|
3232
3239
|
// [ OUTPUT ]
|
|
3233
3240
|
// sinks
|
|
3234
3241
|
|
|
3235
|
-
constructor({ name='NO NAME', sources, intent, request, model, response, view, children={}, components={}, initialState, calculated, storeCalculatedInState=true, DOMSourceName='DOM', stateSourceName='STATE', requestSourceName='HTTP', debug=false }) {
|
|
3242
|
+
constructor({ name='NO NAME', sources, intent, request, model, context, response, view, children={}, components={}, initialState, calculated, storeCalculatedInState=true, DOMSourceName='DOM', stateSourceName='STATE', requestSourceName='HTTP', debug=false }) {
|
|
3236
3243
|
if (!sources || typeof sources != 'object') throw new Error('Missing or invalid sources')
|
|
3237
3244
|
|
|
3238
3245
|
this.name = name;
|
|
@@ -3240,6 +3247,7 @@ class Component {
|
|
|
3240
3247
|
this.intent = intent;
|
|
3241
3248
|
this.request = request;
|
|
3242
3249
|
this.model = model;
|
|
3250
|
+
this.context = context;
|
|
3243
3251
|
this.response = response;
|
|
3244
3252
|
this.view = view;
|
|
3245
3253
|
this.children = children;
|
|
@@ -3259,7 +3267,7 @@ class Component {
|
|
|
3259
3267
|
|
|
3260
3268
|
if (state$) {
|
|
3261
3269
|
this.currentState = initialState || {};
|
|
3262
|
-
this.sources[
|
|
3270
|
+
this.sources[stateSourceName] = new state.StateSource(state$.map(val => {
|
|
3263
3271
|
this.currentState = val;
|
|
3264
3272
|
return val
|
|
3265
3273
|
}));
|
|
@@ -3282,6 +3290,7 @@ class Component {
|
|
|
3282
3290
|
this.initAction$();
|
|
3283
3291
|
this.initResponse$();
|
|
3284
3292
|
this.initState();
|
|
3293
|
+
this.initContext();
|
|
3285
3294
|
this.initModel$();
|
|
3286
3295
|
this.initSendResponse$();
|
|
3287
3296
|
this.initChildren$();
|
|
@@ -3455,6 +3464,61 @@ class Component {
|
|
|
3455
3464
|
}
|
|
3456
3465
|
}
|
|
3457
3466
|
|
|
3467
|
+
initContext() {
|
|
3468
|
+
if (!this.context && !this.sources.__parentContext$) {
|
|
3469
|
+
this.context$ = xs$1.of({});
|
|
3470
|
+
return
|
|
3471
|
+
}
|
|
3472
|
+
const repeatChecker = (a, b) => {
|
|
3473
|
+
if (a === b) return true
|
|
3474
|
+
if (typeof a !== 'object' || typeof b !== 'object') {
|
|
3475
|
+
return a === b
|
|
3476
|
+
}
|
|
3477
|
+
const entriesA = Object.entries(a);
|
|
3478
|
+
const entriesB = Object.entries(b);
|
|
3479
|
+
if (entriesA.length === 0 && entriesB.length === 0) return true
|
|
3480
|
+
if (entriesA.length !== entriesB.length) return false
|
|
3481
|
+
return entriesA.every(([name, value]) => {
|
|
3482
|
+
return b[name] === value
|
|
3483
|
+
})
|
|
3484
|
+
};
|
|
3485
|
+
|
|
3486
|
+
const state$ = this.sources[this.stateSourceName]?.stream.startWith({}).compose(_default$5(repeatChecker)) || xs$1.never();
|
|
3487
|
+
const parentContext$ = this.sources.__parentContext$.startWith({}).compose(_default$5(repeatChecker)) || xs$1.of({});
|
|
3488
|
+
if (this.context && typeof this.context !== 'object') {
|
|
3489
|
+
console.error(`[${this.name}] Context must be an object mapping names to values of functions: ignoring provided ${ typeof this.context }`);
|
|
3490
|
+
}
|
|
3491
|
+
this.context$ = xs$1.combine(state$, parentContext$)
|
|
3492
|
+
.map(([_, parent]) => {
|
|
3493
|
+
const _parent = typeof parent === 'object' ? parent : {};
|
|
3494
|
+
const context = typeof this.context === 'object' ? this.context : {};
|
|
3495
|
+
const state = this.currentState;
|
|
3496
|
+
const values = Object.entries(context).reduce((acc, current) => {
|
|
3497
|
+
const [name, value] = current;
|
|
3498
|
+
let _value;
|
|
3499
|
+
const valueType = typeof value;
|
|
3500
|
+
if (valueType === 'string') {
|
|
3501
|
+
_value = state[value];
|
|
3502
|
+
} else if (valueType === 'boolean') {
|
|
3503
|
+
_value = state[name];
|
|
3504
|
+
} else if (valueType === 'function') {
|
|
3505
|
+
_value = value(state);
|
|
3506
|
+
} else {
|
|
3507
|
+
console.error(`[${ this.name }] Invalid context entry '${ name }': must be the name of a state property or a function returning a value to use`);
|
|
3508
|
+
return acc
|
|
3509
|
+
}
|
|
3510
|
+
acc[name] = _value;
|
|
3511
|
+
return acc
|
|
3512
|
+
}, {});
|
|
3513
|
+
const newContext = { ..._parent, ...values };
|
|
3514
|
+
this.currentContext = newContext;
|
|
3515
|
+
return newContext
|
|
3516
|
+
})
|
|
3517
|
+
.compose(_default$5(repeatChecker))
|
|
3518
|
+
.startWith({});
|
|
3519
|
+
this.context$.subscribe({ next: _ => _ });
|
|
3520
|
+
}
|
|
3521
|
+
|
|
3458
3522
|
initModel$() {
|
|
3459
3523
|
if (typeof this.model == 'undefined') {
|
|
3460
3524
|
this.model$ = this.sourceNames.reduce((a,s) => {
|
|
@@ -3504,7 +3568,7 @@ class Component {
|
|
|
3504
3568
|
return `State reducer added: <${ action }>`
|
|
3505
3569
|
} else {
|
|
3506
3570
|
const extra = data && (data.type || data.command || data.name || data.key || (Array.isArray(data) && 'Array') || data);
|
|
3507
|
-
return `Data sent to [${ sink }]: <${ action }> ${ extra }`
|
|
3571
|
+
return `Data sent to [${ sink }]: <${ action }> ${ JSON.stringify(extra) }`
|
|
3508
3572
|
}
|
|
3509
3573
|
}));
|
|
3510
3574
|
|
|
@@ -3730,7 +3794,7 @@ class Component {
|
|
|
3730
3794
|
return acc
|
|
3731
3795
|
}, {});
|
|
3732
3796
|
|
|
3733
|
-
const newState = { ...state, ...calculated };
|
|
3797
|
+
const newState = { ...state, ...calculated, __context: this.currentContext };
|
|
3734
3798
|
|
|
3735
3799
|
lastState = state;
|
|
3736
3800
|
lastResult = newState;
|
|
@@ -3742,7 +3806,7 @@ class Component {
|
|
|
3742
3806
|
cleanupCalculated(incomingState) {
|
|
3743
3807
|
if (!incomingState || typeof incomingState !== 'object' || incomingState instanceof Array) return incomingState
|
|
3744
3808
|
const state = this.storeCalculatedInState ? this.addCalculated(incomingState) : incomingState;
|
|
3745
|
-
const { __props, __children, ...sanitized } = state;
|
|
3809
|
+
const { __props, __children, __context, ...sanitized } = state;
|
|
3746
3810
|
const copy = { ...sanitized };
|
|
3747
3811
|
if (!this.calculated) return copy
|
|
3748
3812
|
const keys = Object.keys(this.calculated);
|
|
@@ -3764,10 +3828,10 @@ class Component {
|
|
|
3764
3828
|
const stateStream = (enhancedState && enhancedState.stream) || xs$1.never();
|
|
3765
3829
|
|
|
3766
3830
|
const objRepeatChecker = (a, b) => {
|
|
3767
|
-
const { state, sygnalFactory, __props, __children, ...sanitized } = a;
|
|
3831
|
+
const { state, sygnalFactory, __props, __children, __context, ...sanitized } = a;
|
|
3768
3832
|
const keys = Object.keys(sanitized);
|
|
3769
3833
|
if (keys.length === 0) {
|
|
3770
|
-
const { state, sygnalFactory, __props, __children, ...sanitizedB } = b;
|
|
3834
|
+
const { state, sygnalFactory, __props, __children, __context, ...sanitizedB } = b;
|
|
3771
3835
|
return Object.keys(sanitizedB).length === 0
|
|
3772
3836
|
}
|
|
3773
3837
|
return keys.every(key => a[key] === b[key])
|
|
@@ -3792,6 +3856,10 @@ class Component {
|
|
|
3792
3856
|
renderParams.__children = this.sources.children$.compose(_default$5(arrRepeatChecker));
|
|
3793
3857
|
}
|
|
3794
3858
|
|
|
3859
|
+
if (this.context$) {
|
|
3860
|
+
renderParams.__context = this.context$.compose(_default$5(objRepeatChecker));
|
|
3861
|
+
}
|
|
3862
|
+
|
|
3795
3863
|
const names = [];
|
|
3796
3864
|
const streams = [];
|
|
3797
3865
|
|
|
@@ -3803,18 +3871,18 @@ class Component {
|
|
|
3803
3871
|
const combined = xs$1.combine(...streams)
|
|
3804
3872
|
// map the streams from an array back to an object with the render parameter names as the keys
|
|
3805
3873
|
.map(arr => {
|
|
3806
|
-
|
|
3874
|
+
const params = names.reduce((acc, name, index) => {
|
|
3807
3875
|
acc[name] = arr[index];
|
|
3808
3876
|
if (name === 'state') acc[this.stateSourceName] = arr[index];
|
|
3809
3877
|
return acc
|
|
3810
|
-
}, {})
|
|
3878
|
+
}, {});
|
|
3879
|
+
return params
|
|
3811
3880
|
});
|
|
3812
3881
|
|
|
3813
3882
|
return combined
|
|
3814
3883
|
}
|
|
3815
3884
|
|
|
3816
3885
|
instantiateSubComponents(vDom$) {
|
|
3817
|
-
let count = 0;
|
|
3818
3886
|
return vDom$.fold((previousComponents, vDom) => {
|
|
3819
3887
|
const componentNames = Object.keys(this.components);
|
|
3820
3888
|
const foundComponents = getComponents(vDom, componentNames);
|
|
@@ -3845,7 +3913,6 @@ class Component {
|
|
|
3845
3913
|
|
|
3846
3914
|
|
|
3847
3915
|
if (previousComponents[id]) {
|
|
3848
|
-
if (this.debug) console.log(this.name, 'sameful', count++);
|
|
3849
3916
|
const entry = previousComponents[id];
|
|
3850
3917
|
acc[id] = entry;
|
|
3851
3918
|
entry.props$.shamefullySendNext(props);
|
|
@@ -3854,8 +3921,6 @@ class Component {
|
|
|
3854
3921
|
return acc
|
|
3855
3922
|
}
|
|
3856
3923
|
|
|
3857
|
-
if (this.debug) console.log(this.name, 'non-shameful', count++);
|
|
3858
|
-
|
|
3859
3924
|
const props$ = xs$1.create().startWith(props);
|
|
3860
3925
|
const children$ = xs$1.create().startWith(children);
|
|
3861
3926
|
|
|
@@ -3914,19 +3979,18 @@ class Component {
|
|
|
3914
3979
|
|
|
3915
3980
|
const combined$ = xs$1.combine(this.sources[this.stateSourceName].stream.startWith(this.currentState), props$, children$)
|
|
3916
3981
|
.map(([state, __props, __children]) => {
|
|
3917
|
-
return typeof state === 'object' ? { ...this.addCalculated(state), __props, __children } : { value: state, __props, __children }
|
|
3982
|
+
return typeof state === 'object' ? { ...this.addCalculated(state), __props, __children, __context: this.currentContext } : { value: state, __props, __children, __context: this.currentContext }
|
|
3918
3983
|
});
|
|
3919
3984
|
|
|
3920
3985
|
const stateSource = new state.StateSource(combined$);
|
|
3921
3986
|
const stateField = props.from;
|
|
3922
|
-
props.filter;
|
|
3923
3987
|
let lense;
|
|
3924
3988
|
|
|
3925
3989
|
const factory = typeof props.of === 'function' ? props.of : this.components[props.of];
|
|
3926
3990
|
|
|
3927
3991
|
const sanitizeItems = item => {
|
|
3928
3992
|
if (typeof item === 'object') {
|
|
3929
|
-
const { __props, __children, ...sanitized } = item;
|
|
3993
|
+
const { __props, __children, __context, ...sanitized } = item;
|
|
3930
3994
|
return sanitized
|
|
3931
3995
|
} else {
|
|
3932
3996
|
return item
|
|
@@ -3938,7 +4002,7 @@ class Component {
|
|
|
3938
4002
|
const { __props, __children } = state;
|
|
3939
4003
|
if (!Array.isArray(state[stateField])) return []
|
|
3940
4004
|
return state[stateField].map(item => {
|
|
3941
|
-
return typeof item === 'object' ? { ...item, __props, __children } : { value: item, __props, __children }
|
|
4005
|
+
return typeof item === 'object' ? { ...item, __props, __children, __context: this.currentContext } : { value: item, __props, __children, __context: this.currentContext }
|
|
3942
4006
|
})
|
|
3943
4007
|
},
|
|
3944
4008
|
set: (oldState, newState) => {
|
|
@@ -3962,7 +4026,7 @@ class Component {
|
|
|
3962
4026
|
};
|
|
3963
4027
|
} else if (typeof stateField === 'string') {
|
|
3964
4028
|
if (typeof this.currentState === 'object') {
|
|
3965
|
-
if(!(stateField in this.currentState) && !(stateField in this.calculated)) {
|
|
4029
|
+
if(!(this.currentState && stateField in this.currentState) && !(this.calculated && stateField in this.calculated)) {
|
|
3966
4030
|
console.error(`Collection component in ${ this.name } is attempting to use non-existent state property '${ stateField }': To fix this error, specify a valid array property on the state. Attempting to use parent component state.`);
|
|
3967
4031
|
lense = undefined;
|
|
3968
4032
|
} else if (!Array.isArray(this.currentState[stateField])) {
|
|
@@ -4001,7 +4065,7 @@ class Component {
|
|
|
4001
4065
|
lense = undefined;
|
|
4002
4066
|
}
|
|
4003
4067
|
|
|
4004
|
-
const sources = { ...this.sources, [this.stateSourceName]: stateSource, props$, children$ };
|
|
4068
|
+
const sources = { ...this.sources, [this.stateSourceName]: stateSource, props$, children$, __parentContext$: this.context$ };
|
|
4005
4069
|
const sink$ = collection(factory, lense, { container: null })(sources);
|
|
4006
4070
|
if (typeof sink$ !== 'object') {
|
|
4007
4071
|
throw new Error('Invalid sinks returned from component factory of collection element')
|
|
@@ -4016,7 +4080,7 @@ class Component {
|
|
|
4016
4080
|
|
|
4017
4081
|
const combined$ = xs$1.combine(this.sources[this.stateSourceName].stream.startWith(this.currentState), props$, children$)
|
|
4018
4082
|
.map(([state, __props, __children]) => {
|
|
4019
|
-
return typeof state === 'object' ? { ...this.addCalculated(state), __props, __children } : { value: state, __props, __children }
|
|
4083
|
+
return typeof state === 'object' ? { ...this.addCalculated(state), __props, __children, __context: this.currentContext } : { value: state, __props, __children, __context: this.currentContext }
|
|
4020
4084
|
});
|
|
4021
4085
|
|
|
4022
4086
|
const stateSource = new state.StateSource(combined$);
|
|
@@ -4026,7 +4090,7 @@ class Component {
|
|
|
4026
4090
|
const fieldLense = {
|
|
4027
4091
|
get: state => {
|
|
4028
4092
|
const { __props, __children } = state;
|
|
4029
|
-
return (typeof state[stateField] === 'object' && !(state[stateField] instanceof Array)) ? { ...state[stateField], __props, __children } : { value: state[stateField], __props, __children }
|
|
4093
|
+
return (typeof state[stateField] === 'object' && !(state[stateField] instanceof Array)) ? { ...state[stateField], __props, __children, __context: this.currentContext } : { value: state[stateField], __props, __children, __context: this.currentContext }
|
|
4030
4094
|
},
|
|
4031
4095
|
set: (oldState, newState) => {
|
|
4032
4096
|
if (this.calculated && stateField in this.calculated) {
|
|
@@ -4034,7 +4098,7 @@ class Component {
|
|
|
4034
4098
|
return oldState
|
|
4035
4099
|
}
|
|
4036
4100
|
if (typeof newState !== 'object' || newState instanceof Array) return { ...oldState, [stateField]: newState }
|
|
4037
|
-
const { __props, __children, ...sanitized } = newState;
|
|
4101
|
+
const { __props, __children, __context, ...sanitized } = newState;
|
|
4038
4102
|
return { ...oldState, [stateField]: sanitized }
|
|
4039
4103
|
}
|
|
4040
4104
|
};
|
|
@@ -4043,7 +4107,7 @@ class Component {
|
|
|
4043
4107
|
get: state => state,
|
|
4044
4108
|
set: (oldState, newState) => {
|
|
4045
4109
|
if (typeof newState !== 'object' || newState instanceof Array) return newState
|
|
4046
|
-
const { __props, __children, ...sanitized } = newState;
|
|
4110
|
+
const { __props, __children, __context, ...sanitized } = newState;
|
|
4047
4111
|
return sanitized
|
|
4048
4112
|
}
|
|
4049
4113
|
};
|
|
@@ -4065,7 +4129,7 @@ class Component {
|
|
|
4065
4129
|
}
|
|
4066
4130
|
|
|
4067
4131
|
const switchableComponents = props.of;
|
|
4068
|
-
const sources = { ...this.sources, [this.stateSourceName]: stateSource, props$, children$ };
|
|
4132
|
+
const sources = { ...this.sources, [this.stateSourceName]: stateSource, props$, children$, __parentContext$: this.context$ };
|
|
4069
4133
|
|
|
4070
4134
|
const sink$ = isolate(switchable(switchableComponents, props$.map(props => props.current)), { [this.stateSourceName]: lense })(sources);
|
|
4071
4135
|
|
|
@@ -4084,7 +4148,7 @@ class Component {
|
|
|
4084
4148
|
|
|
4085
4149
|
const combined$ = xs$1.combine(this.sources[this.stateSourceName].stream.startWith(this.currentState), props$, children$)
|
|
4086
4150
|
.map(([state, __props, __children]) => {
|
|
4087
|
-
return typeof state === 'object' ? { ...this.addCalculated(state), __props, __children } : { value: state, __props, __children }
|
|
4151
|
+
return typeof state === 'object' ? { ...this.addCalculated(state), __props, __children, __context: this.currentContext } : { value: state, __props, __children, __context: this.currentContext }
|
|
4088
4152
|
});
|
|
4089
4153
|
|
|
4090
4154
|
const stateSource = new state.StateSource(combined$);
|
|
@@ -4101,7 +4165,7 @@ class Component {
|
|
|
4101
4165
|
const fieldLense = {
|
|
4102
4166
|
get: state => {
|
|
4103
4167
|
const { __props, __children } = state;
|
|
4104
|
-
return typeof state[stateField] === 'object' ? { ...state[stateField], __props, __children } : { value: state[stateField], __props, __children }
|
|
4168
|
+
return typeof state[stateField] === 'object' ? { ...state[stateField], __props, __children, __context: this.currentContext } : { value: state[stateField], __props, __children, __context: this.currentContext }
|
|
4105
4169
|
},
|
|
4106
4170
|
set: (oldState, newState) => {
|
|
4107
4171
|
if (this.calculated && stateField in this.calculated) {
|
|
@@ -4116,7 +4180,7 @@ class Component {
|
|
|
4116
4180
|
get: state => state,
|
|
4117
4181
|
set: (oldState, newState) => {
|
|
4118
4182
|
if (typeof newState !== 'object' || newState instanceof Array) return newState
|
|
4119
|
-
const { __props, __children, ...sanitized } = newState;
|
|
4183
|
+
const { __props, __children, __context, ...sanitized } = newState;
|
|
4120
4184
|
return sanitized
|
|
4121
4185
|
}
|
|
4122
4186
|
};
|
|
@@ -4137,7 +4201,7 @@ class Component {
|
|
|
4137
4201
|
lense = baseLense;
|
|
4138
4202
|
}
|
|
4139
4203
|
|
|
4140
|
-
const sources = { ...this.sources, [this.stateSourceName]: stateSource, props$, children$ };
|
|
4204
|
+
const sources = { ...this.sources, [this.stateSourceName]: stateSource, props$, children$, __parentContext$: this.context$ };
|
|
4141
4205
|
const sink$ = isolate(factory, { [this.stateSourceName]: lense })(sources);
|
|
4142
4206
|
|
|
4143
4207
|
if (typeof sink$ !== 'object') {
|
|
@@ -4232,7 +4296,7 @@ function getComponents(currentElement, componentNames, depth=0, index=0) {
|
|
|
4232
4296
|
const sel = currentElement.sel;
|
|
4233
4297
|
const isCollection = sel && sel.toLowerCase() === 'collection';
|
|
4234
4298
|
const isSwitchable = sel && sel.toLowerCase() === 'switchable';
|
|
4235
|
-
const isComponent = sel && (['collection', 'switchable', 'sygnal-factory', ...componentNames].includes(
|
|
4299
|
+
const isComponent = sel && (['collection', 'switchable', 'sygnal-factory', ...componentNames].includes(sel)) || typeof currentElement.data?.props?.sygnalFactory === 'function';
|
|
4236
4300
|
const props = (currentElement.data && currentElement.data.props) || {};
|
|
4237
4301
|
(currentElement.data && currentElement.data.attrs) || {};
|
|
4238
4302
|
const children = currentElement.children || [];
|
|
@@ -4316,9 +4380,9 @@ function getComponentIdFromElement(el, depth, index) {
|
|
|
4316
4380
|
base = `${date}-${rand}`;
|
|
4317
4381
|
selMap.set(sel, base);
|
|
4318
4382
|
}
|
|
4319
|
-
const uid
|
|
4320
|
-
const props
|
|
4321
|
-
const id
|
|
4383
|
+
const uid = `${base}-${depth}-${index}`;
|
|
4384
|
+
const props = (el.data && el.data.props) || {};
|
|
4385
|
+
const id = (props.id && JSON.stringify(props.id)) || uid;
|
|
4322
4386
|
const fullId = `${ name }::${ id }`;
|
|
4323
4387
|
return fullId
|
|
4324
4388
|
}
|