diff --git a/src/putility/src/concepts/Service.js b/src/putility/src/concepts/Service.js index 57b0ba46..30668d36 100644 --- a/src/putility/src/concepts/Service.js +++ b/src/putility/src/concepts/Service.js @@ -2,6 +2,9 @@ const { AdvancedBase } = require("../AdvancedBase"); const NOOP = async () => {}; +/** Service trait */ +const TService = Symbol('TService'); + /** * Service will be incrementally updated to consolidate * BaseService in Puter's backend with Service in Puter's frontend, @@ -23,23 +26,27 @@ class Service extends AdvancedBase { static create ({ parameters, context }) { const ins = new this(); ins._.context = context; - ins.construct(parameters); + ins.as(TService).construct(parameters); return ins; } - init (...a) { - if ( ! this._init ) return; - return this._init(...a); - } - - construct (o) { - this.$parameters = {}; - for ( const k in o ) this.$parameters[k] = o[k]; - if ( ! this._construct ) return; - return this._construct(o); + static IMPLEMENTS = { + [TService]: { + init (...a) { + if ( ! this._init ) return; + return this._init(...a); + }, + construct (o) { + this.$parameters = {}; + for ( const k in o ) this.$parameters[k] = o[k]; + if ( ! this._construct ) return; + return this._construct(o); + } + } } } module.exports = { + TService, Service, }; diff --git a/src/putility/src/features/PropertiesFeature.js b/src/putility/src/features/PropertiesFeature.js index 90a9572b..b5ec2b22 100644 --- a/src/putility/src/features/PropertiesFeature.js +++ b/src/putility/src/features/PropertiesFeature.js @@ -18,14 +18,15 @@ */ module.exports = { name: 'Properties', + depends: ['Listeners'], install_in_instance: (instance) => { const properties = instance._get_merged_static_object('PROPERTIES'); instance.onchange = (name, callback) => { - instance.__properties[name].listeners.push(callback); + instance._.properties[name].listeners.push(callback); }; - instance.__properties = {}; + instance._.properties = {}; for ( const k in properties ) { const state = { @@ -33,7 +34,7 @@ module.exports = { listeners: [], value: undefined, }; - instance.__properties[k] = state; + instance._.properties[k] = state; if ( typeof properties[k] === 'object' ) { // This will be supported in the future. @@ -54,7 +55,7 @@ module.exports = { return state.value; }, set: (value) => { - for ( const listener of instance.__properties[k].listeners ) { + for ( const listener of instance._.properties[k].listeners ) { listener(value, { old_value: instance[k], }); diff --git a/src/putility/src/features/TraitsFeature.js b/src/putility/src/features/TraitsFeature.js index 2da996b7..ba597251 100644 --- a/src/putility/src/features/TraitsFeature.js +++ b/src/putility/src/features/TraitsFeature.js @@ -30,7 +30,11 @@ module.exports = { for ( const cls of chain ) { const cls_traits = cls.IMPLEMENTS; if ( ! cls_traits ) continue; - for ( const trait_name in cls_traits ) { + const trait_keys = [ + ...Object.getOwnPropertySymbols(cls_traits), + ...Object.keys(cls_traits), + ]; + for ( const trait_name of trait_keys ) { const impl = instance._.impls[trait_name] ?? (instance._.impls[trait_name] = {}); const cls_impl = cls_traits[trait_name]; diff --git a/src/putility/src/system/ServiceManager.js b/src/putility/src/system/ServiceManager.js index 95c5cbbc..a2e67987 100644 --- a/src/putility/src/system/ServiceManager.js +++ b/src/putility/src/system/ServiceManager.js @@ -1,4 +1,5 @@ const { AdvancedBase } = require("../AdvancedBase"); +const { TService } = require("../concepts/Service"); const mkstatus = name => { const c = class { @@ -99,7 +100,9 @@ class ServiceManager extends AdvancedBase { async init_service_ (name) { const entry = this.services_m_[name]; entry.status = new this.constructor.StatusInitializing(); - await entry.instance.init(); + + const service_impl = entry.instance.as(TService); + await service_impl.init(); entry.status = new this.constructor.StatusRunning({ start_ts: new Date(), });