Comparing version 0.3.1-alpha to 0.4.0-next.0
@@ -1,2 +0,2 @@ | ||
function t(t,e,n){Object.defineProperty(t,e,{get:()=>n(),enumerable:!0})}class e extends Error{}class n extends e{}class s extends e{}class i extends class extends class{}{on(t,e){return this.ee.on(t,e)}constructor(){super(),this._cache={},this._context={},this.ee=void 0,this.ee={events:{},emit(t,...e){(this.events[t]||[]).forEach(t=>t(...e))},on(t,e){return(this.events[t]=this.events[t]||[]).push(e),()=>this.events[t]=(this.events[t]||[]).filter(t=>t!==e)}}}get(t){if(null!=this._context[t]){const e=this._cache[t];if(null!=e)return e;const n=(t,e)=>{this._cache[t]=e,this.ee.emit("containerUpserted",{key:t,newContainer:e})},s=this._context[t];if("function"==typeof s){const e=s();return n(t,e),e}return n(t,s),s}throw new n(`Can't find token '${t}' value`)}_updateContext(t){for(const[e,n]of Object.entries(t))null!=this._context[e]&&this.ee.emit("containerUpdated",{key:e,newContainer:n}),this._context[e]=n,this._cache[e]=null,this.ee.emit("containerUpserted",{key:e,newContainer:n})}subscribeToContiner(t,e){var n=this;return this.ee.on("containerUpserted",async function(s){t===s.key&&e(await n.get(t))})}getTokens(){return Object.fromEntries(Object.keys(this._context).map(t=>[t,t]))}}{constructor(){super()}upsert(t){let e="function"==typeof t?t(this.containers,this):t;return this._updateContext(e),this}add(t){let e="function"==typeof t?t(this.containers,this):t,n=Object.keys(this.getTokens()).filter(t=>null!=e[t]);if(0!==n.length)throw new s(`Tokens already exist: ['${n.join("', '")}']`);return this.upsert(e)}_extractTokens(t){return"function"==typeof t?t(this.getTokens()):t}subscribeToContinerSet(t,e){var n=this;let s=this._extractTokens(t);return this.ee.on("containerUpserted",async function(t){s.includes(t.key)&&e(await n.getContainerSet(s))})}async getContainerSet(t){let e=this._extractTokens(t),n=[],s=[];for(let t of e)this.containers[t]instanceof Promise&&(n.push(t),s.push(this.containers[t]));let i={};e.forEach(t=>{i[t]=this.containers[t]});const r=await Promise.all(s);return n.forEach((t,e)=>{i[t]=r[e]}),i}get containers(){let e={};for(let n in this.getTokens())t(e,n,()=>this.get(n));return e}}function r(){return new i}export{i as NodeApi,r as makeRoot}; | ||
function t(t,e,n){Object.defineProperty(t,e,{get:()=>n(),enumerable:!0})}class e extends Error{}class n extends e{}class s extends e{}class i extends class extends class{}{on(t,e){return this.ee.on(t,e)}constructor(){super(),this._cache={},this._context={},this.ee=void 0,this.ee={events:{},emit(t,...e){(this.events[t]||[]).forEach(t=>t(...e))},on(t,e){return(this.events[t]=this.events[t]||[]).push(e),()=>this.events[t]=(this.events[t]||[]).filter(t=>t!==e)}}}get(t){if(null!=this._context[t]){const e=this._cache[t];if(null!=e)return e;const n=(t,e)=>{this._cache[t]=e,this.ee.emit("containerUpserted",{key:t,newContainer:e})},s=this._context[t];if("function"==typeof s){const e=s();return n(t,e),e}return n(t,s),s}throw new n(`Can't find token '${t}' value`)}_updateContext(t){for(const[e,n]of Object.entries(t))null!=this._context[e]&&this.ee.emit("containerUpdated",{key:e,newContainer:n}),this._context[e]=n,this._cache[e]=null,this.ee.emit("containerUpserted",{key:e,newContainer:n})}subscribeToContiner(t,e){var n=this;return this.ee.on("containerUpserted",async function(s){if(t===s.key)try{const s=await n.get(t);e(null,s)}catch(t){e(t,void 0)}})}getTokens(){return Object.fromEntries(Object.keys(this._context).map(t=>[t,t]))}}{constructor(){super()}upsert(t){let e="function"==typeof t?t(this.containers,this):t;return this._updateContext(e),this}add(t){let e="function"==typeof t?t(this.containers,this):t,n=Object.keys(this.getTokens()).filter(t=>null!=e[t]);if(0!==n.length)throw new s(`Tokens already exist: ['${n.join("', '")}']`);return this.upsert(e)}_extractTokens(t){return"function"==typeof t?t(this.getTokens()):t}subscribeToContinerSet(t,e){var n=this;let s=this._extractTokens(t);return this.ee.on("containerUpserted",async function(t){if(s.includes(t.key))try{const t=await n.getContainerSet(s);e(null,t)}catch(t){e(t,void 0)}})}async getContainerSet(t){let e=this._extractTokens(t),n=[],s=[];for(let t of e)this.containers[t]instanceof Promise&&(n.push(t),s.push(this.containers[t]));let i={};e.forEach(t=>{i[t]=this.containers[t]});const r=await Promise.all(s);return n.forEach((t,e)=>{i[t]=r[e]}),i}get containers(){let e={};for(let n in this.getTokens())t(e,n,()=>this.get(n));return e}}function r(){return new i}export{i as NodeApi,r as makeRoot}; | ||
//# sourceMappingURL=iti.modern.js.map |
@@ -1,2 +0,2 @@ | ||
function t(t,e){t.prototype=Object.create(e.prototype),t.prototype.constructor=t,n(t,e)}function e(t){return e=Object.setPrototypeOf?Object.getPrototypeOf:function(t){return t.__proto__||Object.getPrototypeOf(t)},e(t)}function n(t,e){return n=Object.setPrototypeOf||function(t,e){return t.__proto__=e,t},n(t,e)}function r(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Boolean.prototype.valueOf.call(Reflect.construct(Boolean,[],function(){})),!0}catch(t){return!1}}function o(t,e,i){return o=r()?Reflect.construct:function(t,e,r){var o=[null];o.push.apply(o,e);var i=new(Function.bind.apply(t,o));return r&&n(i,r.prototype),i},o.apply(null,arguments)}function i(t){var r="function"==typeof Map?new Map:void 0;return i=function(t){if(null===t||-1===Function.toString.call(t).indexOf("[native code]"))return t;if("function"!=typeof t)throw new TypeError("Super expression must either be null or a function");if(void 0!==r){if(r.has(t))return r.get(t);r.set(t,i)}function i(){return o(t,arguments,e(this).constructor)}return i.prototype=Object.create(t.prototype,{constructor:{value:i,enumerable:!1,writable:!0,configurable:!0}}),n(i,t)},i(t)}function u(t,e){(null==e||e>t.length)&&(e=t.length);for(var n=0,r=new Array(e);n<e;n++)r[n]=t[n];return r}var c=/*#__PURE__*/function(e){function n(){return e.apply(this,arguments)||this}return t(n,e),n}(/*#__PURE__*/i(Error)),a=/*#__PURE__*/function(e){function n(){return e.apply(this,arguments)||this}return t(n,e),n}(c),f=/*#__PURE__*/function(e){function n(){return e.apply(this,arguments)||this}return t(n,e),n}(c),s=/*#__PURE__*/function(e){function n(){return e.call(this)||this}t(n,e);var r,o,i=n.prototype;return i.upsert=function(t){var e="function"==typeof t?t(this.containers,this):t;return this._updateContext(e),this},i.add=function(t){var e="function"==typeof t?t(this.containers,this):t,n=Object.keys(this.getTokens()).filter(function(t){return null!=e[t]});if(0!==n.length)throw new f("Tokens already exist: ['"+n.join("', '")+"']");return this.upsert(e)},i._extractTokens=function(t){return"function"==typeof t?t(this.getTokens()):t},i.subscribeToContinerSet=function(t,e){var n=this,r=this._extractTokens(t);return this.ee.on("containerUpserted",function(t){try{var o=function(){if(r.includes(t.key))return Promise.resolve(n.getContainerSet(r)).then(function(t){e(t)})}();return Promise.resolve(o&&o.then?o.then(function(){}):void 0)}catch(t){return Promise.reject(t)}})},i.getContainerSet=function(t){try{for(var e,n=this,r=n._extractTokens(t),o=[],i=[],c=function(t,e){var n="undefined"!=typeof Symbol&&t[Symbol.iterator]||t["@@iterator"];if(n)return(n=n.call(t)).next.bind(n);if(Array.isArray(t)||(n=function(t,e){if(t){if("string"==typeof t)return u(t,e);var n=Object.prototype.toString.call(t).slice(8,-1);return"Object"===n&&t.constructor&&(n=t.constructor.name),"Map"===n||"Set"===n?Array.from(t):"Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)?u(t,e):void 0}}(t))){n&&(t=n);var r=0;return function(){return r>=t.length?{done:!0}:{done:!1,value:t[r++]}}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}(r);!(e=c()).done;){var a=e.value;n.containers[a]instanceof Promise&&(o.push(a),i.push(n.containers[a]))}var f={};return r.forEach(function(t){f[t]=n.containers[t]}),Promise.resolve(Promise.all(i)).then(function(t){return o.forEach(function(e,n){f[e]=t[n]}),f})}catch(t){return Promise.reject(t)}},r=n,(o=[{key:"containers",get:function(){var t=this,e={},n=function(n){!function(t,e,n){Object.defineProperty(t,e,{get:function(){return n()},enumerable:!0})}(e,n,function(){return t.get(n)})};for(var r in this.getTokens())n(r);return e}}])&&function(t,e){for(var n=0;n<e.length;n++){var r=e[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(t,r.key,r)}}(r.prototype,o),Object.defineProperty(r,"prototype",{writable:!1}),n}(/*#__PURE__*/function(e){t(r,e);var n=r.prototype;function r(){var t;return(t=e.call(this)||this)._cache={},t._context={},t.ee=void 0,t.ee={events:{},emit:function(t){var e=arguments;(this.events[t]||[]).forEach(function(t){return t.apply(void 0,[].slice.call(e,1))})},on:function(t,e){var n=this;return(this.events[t]=this.events[t]||[]).push(e),function(){return n.events[t]=(n.events[t]||[]).filter(function(t){return t!==e})}}},t}return n.on=function(t,e){return this.ee.on(t,e)},n.get=function(t){var e=this;if(null!=this._context[t]){var n=this._cache[t];if(null!=n)return n;var r=function(t,n){e._cache[t]=n,e.ee.emit("containerUpserted",{key:t,newContainer:n})},o=this._context[t];if("function"==typeof o){var i=o();return r(t,i),i}return r(t,o),o}throw new a("Can't find token '"+t+"' value")},n._updateContext=function(t){for(var e=0,n=Object.entries(t);e<n.length;e++){var r=n[e],o=r[0],i=r[1];null!=this._context[o]&&this.ee.emit("containerUpdated",{key:o,newContainer:i}),this._context[o]=i,this._cache[o]=null,this.ee.emit("containerUpserted",{key:o,newContainer:i})}},n.subscribeToContiner=function(t,e){var n=this;return this.ee.on("containerUpserted",function(r){try{var o=function(){if(t===r.key)return Promise.resolve(n.get(t)).then(function(t){e(t)})}();return Promise.resolve(o&&o.then?o.then(function(){}):void 0)}catch(t){return Promise.reject(t)}})},n.getTokens=function(){return Object.fromEntries(Object.keys(this._context).map(function(t){return[t,t]}))},r}(function(){}));function l(){return new s}export{s as NodeApi,l as makeRoot}; | ||
function t(t,n){t.prototype=Object.create(n.prototype),t.prototype.constructor=t,e(t,n)}function n(t){return n=Object.setPrototypeOf?Object.getPrototypeOf:function(t){return t.__proto__||Object.getPrototypeOf(t)},n(t)}function e(t,n){return e=Object.setPrototypeOf||function(t,n){return t.__proto__=n,t},e(t,n)}function r(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Boolean.prototype.valueOf.call(Reflect.construct(Boolean,[],function(){})),!0}catch(t){return!1}}function o(t,n,i){return o=r()?Reflect.construct:function(t,n,r){var o=[null];o.push.apply(o,n);var i=new(Function.bind.apply(t,o));return r&&e(i,r.prototype),i},o.apply(null,arguments)}function i(t){var r="function"==typeof Map?new Map:void 0;return i=function(t){if(null===t||-1===Function.toString.call(t).indexOf("[native code]"))return t;if("function"!=typeof t)throw new TypeError("Super expression must either be null or a function");if(void 0!==r){if(r.has(t))return r.get(t);r.set(t,i)}function i(){return o(t,arguments,n(this).constructor)}return i.prototype=Object.create(t.prototype,{constructor:{value:i,enumerable:!1,writable:!0,configurable:!0}}),e(i,t)},i(t)}function u(t,n){(null==n||n>t.length)&&(n=t.length);for(var e=0,r=new Array(n);e<n;e++)r[e]=t[e];return r}var c=/*#__PURE__*/function(n){function e(){return n.apply(this,arguments)||this}return t(e,n),e}(/*#__PURE__*/i(Error)),f=/*#__PURE__*/function(n){function e(){return n.apply(this,arguments)||this}return t(e,n),e}(c),a=/*#__PURE__*/function(n){function e(){return n.apply(this,arguments)||this}return t(e,n),e}(c);function s(t,n){try{var e=t()}catch(t){return n(t)}return e&&e.then?e.then(void 0,n):e}var l=/*#__PURE__*/function(n){function e(){return n.call(this)||this}t(e,n);var r,o,i=e.prototype;return i.upsert=function(t){var n="function"==typeof t?t(this.containers,this):t;return this._updateContext(n),this},i.add=function(t){var n="function"==typeof t?t(this.containers,this):t,e=Object.keys(this.getTokens()).filter(function(t){return null!=n[t]});if(0!==e.length)throw new a("Tokens already exist: ['"+e.join("', '")+"']");return this.upsert(n)},i._extractTokens=function(t){return"function"==typeof t?t(this.getTokens()):t},i.subscribeToContinerSet=function(t,n){var e=this,r=this._extractTokens(t);return this.ee.on("containerUpserted",function(t){try{var o=function(){if(r.includes(t.key)){var o=s(function(){return Promise.resolve(e.getContainerSet(r)).then(function(t){n(null,t)})},function(t){n(t,void 0)});if(o&&o.then)return o.then(function(){})}}();return Promise.resolve(o&&o.then?o.then(function(){}):void 0)}catch(t){return Promise.reject(t)}})},i.getContainerSet=function(t){try{for(var n,e=this,r=e._extractTokens(t),o=[],i=[],c=function(t,n){var e="undefined"!=typeof Symbol&&t[Symbol.iterator]||t["@@iterator"];if(e)return(e=e.call(t)).next.bind(e);if(Array.isArray(t)||(e=function(t,n){if(t){if("string"==typeof t)return u(t,n);var e=Object.prototype.toString.call(t).slice(8,-1);return"Object"===e&&t.constructor&&(e=t.constructor.name),"Map"===e||"Set"===e?Array.from(t):"Arguments"===e||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(e)?u(t,n):void 0}}(t))){e&&(t=e);var r=0;return function(){return r>=t.length?{done:!0}:{done:!1,value:t[r++]}}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}(r);!(n=c()).done;){var f=n.value;e.containers[f]instanceof Promise&&(o.push(f),i.push(e.containers[f]))}var a={};return r.forEach(function(t){a[t]=e.containers[t]}),Promise.resolve(Promise.all(i)).then(function(t){return o.forEach(function(n,e){a[n]=t[e]}),a})}catch(t){return Promise.reject(t)}},r=e,(o=[{key:"containers",get:function(){var t=this,n={},e=function(e){!function(t,n,e){Object.defineProperty(t,n,{get:function(){return e()},enumerable:!0})}(n,e,function(){return t.get(e)})};for(var r in this.getTokens())e(r);return n}}])&&function(t,n){for(var e=0;e<n.length;e++){var r=n[e];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(t,r.key,r)}}(r.prototype,o),Object.defineProperty(r,"prototype",{writable:!1}),e}(/*#__PURE__*/function(n){t(r,n);var e=r.prototype;function r(){var t;return(t=n.call(this)||this)._cache={},t._context={},t.ee=void 0,t.ee={events:{},emit:function(t){var n=arguments;(this.events[t]||[]).forEach(function(t){return t.apply(void 0,[].slice.call(n,1))})},on:function(t,n){var e=this;return(this.events[t]=this.events[t]||[]).push(n),function(){return e.events[t]=(e.events[t]||[]).filter(function(t){return t!==n})}}},t}return e.on=function(t,n){return this.ee.on(t,n)},e.get=function(t){var n=this;if(null!=this._context[t]){var e=this._cache[t];if(null!=e)return e;var r=function(t,e){n._cache[t]=e,n.ee.emit("containerUpserted",{key:t,newContainer:e})},o=this._context[t];if("function"==typeof o){var i=o();return r(t,i),i}return r(t,o),o}throw new f("Can't find token '"+t+"' value")},e._updateContext=function(t){for(var n=0,e=Object.entries(t);n<e.length;n++){var r=e[n],o=r[0],i=r[1];null!=this._context[o]&&this.ee.emit("containerUpdated",{key:o,newContainer:i}),this._context[o]=i,this._cache[o]=null,this.ee.emit("containerUpserted",{key:o,newContainer:i})}},e.subscribeToContiner=function(t,n){var e=this;return this.ee.on("containerUpserted",function(r){try{var o=function(){if(t===r.key){var o=s(function(){return Promise.resolve(e.get(t)).then(function(t){n(null,t)})},function(t){n(t,void 0)});if(o&&o.then)return o.then(function(){})}}();return Promise.resolve(o&&o.then?o.then(function(){}):void 0)}catch(t){return Promise.reject(t)}})},e.getTokens=function(){return Object.fromEntries(Object.keys(this._context).map(function(t){return[t,t]}))},r}(function(){}));function h(){return new l}export{l as NodeApi,h as makeRoot}; | ||
//# sourceMappingURL=iti.module.js.map |
@@ -1,2 +0,2 @@ | ||
!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?e(exports):"function"==typeof define&&define.amd?define(["exports"],e):e((t||self).iti={})}(this,function(t){function e(t,e){t.prototype=Object.create(e.prototype),t.prototype.constructor=t,r(t,e)}function n(t){return n=Object.setPrototypeOf?Object.getPrototypeOf:function(t){return t.__proto__||Object.getPrototypeOf(t)},n(t)}function r(t,e){return r=Object.setPrototypeOf||function(t,e){return t.__proto__=e,t},r(t,e)}function o(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Boolean.prototype.valueOf.call(Reflect.construct(Boolean,[],function(){})),!0}catch(t){return!1}}function i(t,e,n){return i=o()?Reflect.construct:function(t,e,n){var o=[null];o.push.apply(o,e);var i=new(Function.bind.apply(t,o));return n&&r(i,n.prototype),i},i.apply(null,arguments)}function u(t){var e="function"==typeof Map?new Map:void 0;return u=function(t){if(null===t||-1===Function.toString.call(t).indexOf("[native code]"))return t;if("function"!=typeof t)throw new TypeError("Super expression must either be null or a function");if(void 0!==e){if(e.has(t))return e.get(t);e.set(t,o)}function o(){return i(t,arguments,n(this).constructor)}return o.prototype=Object.create(t.prototype,{constructor:{value:o,enumerable:!1,writable:!0,configurable:!0}}),r(o,t)},u(t)}function c(t,e){(null==e||e>t.length)&&(e=t.length);for(var n=0,r=new Array(e);n<e;n++)r[n]=t[n];return r}var f=/*#__PURE__*/function(t){function n(){return t.apply(this,arguments)||this}return e(n,t),n}(/*#__PURE__*/u(Error)),a=/*#__PURE__*/function(t){function n(){return t.apply(this,arguments)||this}return e(n,t),n}(f),s=/*#__PURE__*/function(t){function n(){return t.apply(this,arguments)||this}return e(n,t),n}(f),l=/*#__PURE__*/function(t){e(r,t);var n=r.prototype;function r(){var e;return(e=t.call(this)||this)._cache={},e._context={},e.ee=void 0,e.ee={events:{},emit:function(t){var e=arguments;(this.events[t]||[]).forEach(function(t){return t.apply(void 0,[].slice.call(e,1))})},on:function(t,e){var n=this;return(this.events[t]=this.events[t]||[]).push(e),function(){return n.events[t]=(n.events[t]||[]).filter(function(t){return t!==e})}}},e}return n.on=function(t,e){return this.ee.on(t,e)},n.get=function(t){var e=this;if(null!=this._context[t]){var n=this._cache[t];if(null!=n)return n;var r=function(t,n){e._cache[t]=n,e.ee.emit("containerUpserted",{key:t,newContainer:n})},o=this._context[t];if("function"==typeof o){var i=o();return r(t,i),i}return r(t,o),o}throw new a("Can't find token '"+t+"' value")},n._updateContext=function(t){for(var e=0,n=Object.entries(t);e<n.length;e++){var r=n[e],o=r[0],i=r[1];null!=this._context[o]&&this.ee.emit("containerUpdated",{key:o,newContainer:i}),this._context[o]=i,this._cache[o]=null,this.ee.emit("containerUpserted",{key:o,newContainer:i})}},n.subscribeToContiner=function(t,e){var n=this;return this.ee.on("containerUpserted",function(r){try{var o=function(){if(t===r.key)return Promise.resolve(n.get(t)).then(function(t){e(t)})}();return Promise.resolve(o&&o.then?o.then(function(){}):void 0)}catch(t){return Promise.reject(t)}})},n.getTokens=function(){return Object.fromEntries(Object.keys(this._context).map(function(t){return[t,t]}))},r}(function(){}),p=/*#__PURE__*/function(t){function n(){return t.call(this)||this}e(n,t);var r,o,i=n.prototype;return i.upsert=function(t){var e="function"==typeof t?t(this.containers,this):t;return this._updateContext(e),this},i.add=function(t){var e="function"==typeof t?t(this.containers,this):t,n=Object.keys(this.getTokens()).filter(function(t){return null!=e[t]});if(0!==n.length)throw new s("Tokens already exist: ['"+n.join("', '")+"']");return this.upsert(e)},i._extractTokens=function(t){return"function"==typeof t?t(this.getTokens()):t},i.subscribeToContinerSet=function(t,e){var n=this,r=this._extractTokens(t);return this.ee.on("containerUpserted",function(t){try{var o=function(){if(r.includes(t.key))return Promise.resolve(n.getContainerSet(r)).then(function(t){e(t)})}();return Promise.resolve(o&&o.then?o.then(function(){}):void 0)}catch(t){return Promise.reject(t)}})},i.getContainerSet=function(t){try{for(var e,n=this,r=n._extractTokens(t),o=[],i=[],u=function(t,e){var n="undefined"!=typeof Symbol&&t[Symbol.iterator]||t["@@iterator"];if(n)return(n=n.call(t)).next.bind(n);if(Array.isArray(t)||(n=function(t,e){if(t){if("string"==typeof t)return c(t,e);var n=Object.prototype.toString.call(t).slice(8,-1);return"Object"===n&&t.constructor&&(n=t.constructor.name),"Map"===n||"Set"===n?Array.from(t):"Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)?c(t,e):void 0}}(t))){n&&(t=n);var r=0;return function(){return r>=t.length?{done:!0}:{done:!1,value:t[r++]}}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}(r);!(e=u()).done;){var f=e.value;n.containers[f]instanceof Promise&&(o.push(f),i.push(n.containers[f]))}var a={};return r.forEach(function(t){a[t]=n.containers[t]}),Promise.resolve(Promise.all(i)).then(function(t){return o.forEach(function(e,n){a[e]=t[n]}),a})}catch(t){return Promise.reject(t)}},r=n,(o=[{key:"containers",get:function(){var t=this,e={},n=function(n){!function(t,e,n){Object.defineProperty(t,e,{get:function(){return n()},enumerable:!0})}(e,n,function(){return t.get(n)})};for(var r in this.getTokens())n(r);return e}}])&&function(t,e){for(var n=0;n<e.length;n++){var r=e[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(t,r.key,r)}}(r.prototype,o),Object.defineProperty(r,"prototype",{writable:!1}),n}(l);t.NodeApi=p,t.makeRoot=function(){return new p}}); | ||
!function(t,n){"object"==typeof exports&&"undefined"!=typeof module?n(exports):"function"==typeof define&&define.amd?define(["exports"],n):n((t||self).iti={})}(this,function(t){function n(t,n){t.prototype=Object.create(n.prototype),t.prototype.constructor=t,r(t,n)}function e(t){return e=Object.setPrototypeOf?Object.getPrototypeOf:function(t){return t.__proto__||Object.getPrototypeOf(t)},e(t)}function r(t,n){return r=Object.setPrototypeOf||function(t,n){return t.__proto__=n,t},r(t,n)}function o(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Boolean.prototype.valueOf.call(Reflect.construct(Boolean,[],function(){})),!0}catch(t){return!1}}function i(t,n,e){return i=o()?Reflect.construct:function(t,n,e){var o=[null];o.push.apply(o,n);var i=new(Function.bind.apply(t,o));return e&&r(i,e.prototype),i},i.apply(null,arguments)}function u(t){var n="function"==typeof Map?new Map:void 0;return u=function(t){if(null===t||-1===Function.toString.call(t).indexOf("[native code]"))return t;if("function"!=typeof t)throw new TypeError("Super expression must either be null or a function");if(void 0!==n){if(n.has(t))return n.get(t);n.set(t,o)}function o(){return i(t,arguments,e(this).constructor)}return o.prototype=Object.create(t.prototype,{constructor:{value:o,enumerable:!1,writable:!0,configurable:!0}}),r(o,t)},u(t)}function c(t,n){(null==n||n>t.length)&&(n=t.length);for(var e=0,r=new Array(n);e<n;e++)r[e]=t[e];return r}var f=/*#__PURE__*/function(t){function e(){return t.apply(this,arguments)||this}return n(e,t),e}(/*#__PURE__*/u(Error)),a=/*#__PURE__*/function(t){function e(){return t.apply(this,arguments)||this}return n(e,t),e}(f),s=/*#__PURE__*/function(t){function e(){return t.apply(this,arguments)||this}return n(e,t),e}(f);function l(t,n){try{var e=t()}catch(t){return n(t)}return e&&e.then?e.then(void 0,n):e}var h=/*#__PURE__*/function(t){n(r,t);var e=r.prototype;function r(){var n;return(n=t.call(this)||this)._cache={},n._context={},n.ee=void 0,n.ee={events:{},emit:function(t){var n=arguments;(this.events[t]||[]).forEach(function(t){return t.apply(void 0,[].slice.call(n,1))})},on:function(t,n){var e=this;return(this.events[t]=this.events[t]||[]).push(n),function(){return e.events[t]=(e.events[t]||[]).filter(function(t){return t!==n})}}},n}return e.on=function(t,n){return this.ee.on(t,n)},e.get=function(t){var n=this;if(null!=this._context[t]){var e=this._cache[t];if(null!=e)return e;var r=function(t,e){n._cache[t]=e,n.ee.emit("containerUpserted",{key:t,newContainer:e})},o=this._context[t];if("function"==typeof o){var i=o();return r(t,i),i}return r(t,o),o}throw new a("Can't find token '"+t+"' value")},e._updateContext=function(t){for(var n=0,e=Object.entries(t);n<e.length;n++){var r=e[n],o=r[0],i=r[1];null!=this._context[o]&&this.ee.emit("containerUpdated",{key:o,newContainer:i}),this._context[o]=i,this._cache[o]=null,this.ee.emit("containerUpserted",{key:o,newContainer:i})}},e.subscribeToContiner=function(t,n){var e=this;return this.ee.on("containerUpserted",function(r){try{var o=function(){if(t===r.key){var o=l(function(){return Promise.resolve(e.get(t)).then(function(t){n(null,t)})},function(t){n(t,void 0)});if(o&&o.then)return o.then(function(){})}}();return Promise.resolve(o&&o.then?o.then(function(){}):void 0)}catch(t){return Promise.reject(t)}})},e.getTokens=function(){return Object.fromEntries(Object.keys(this._context).map(function(t){return[t,t]}))},r}(function(){}),p=/*#__PURE__*/function(t){function e(){return t.call(this)||this}n(e,t);var r,o,i=e.prototype;return i.upsert=function(t){var n="function"==typeof t?t(this.containers,this):t;return this._updateContext(n),this},i.add=function(t){var n="function"==typeof t?t(this.containers,this):t,e=Object.keys(this.getTokens()).filter(function(t){return null!=n[t]});if(0!==e.length)throw new s("Tokens already exist: ['"+e.join("', '")+"']");return this.upsert(n)},i._extractTokens=function(t){return"function"==typeof t?t(this.getTokens()):t},i.subscribeToContinerSet=function(t,n){var e=this,r=this._extractTokens(t);return this.ee.on("containerUpserted",function(t){try{var o=function(){if(r.includes(t.key)){var o=l(function(){return Promise.resolve(e.getContainerSet(r)).then(function(t){n(null,t)})},function(t){n(t,void 0)});if(o&&o.then)return o.then(function(){})}}();return Promise.resolve(o&&o.then?o.then(function(){}):void 0)}catch(t){return Promise.reject(t)}})},i.getContainerSet=function(t){try{for(var n,e=this,r=e._extractTokens(t),o=[],i=[],u=function(t,n){var e="undefined"!=typeof Symbol&&t[Symbol.iterator]||t["@@iterator"];if(e)return(e=e.call(t)).next.bind(e);if(Array.isArray(t)||(e=function(t,n){if(t){if("string"==typeof t)return c(t,n);var e=Object.prototype.toString.call(t).slice(8,-1);return"Object"===e&&t.constructor&&(e=t.constructor.name),"Map"===e||"Set"===e?Array.from(t):"Arguments"===e||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(e)?c(t,n):void 0}}(t))){e&&(t=e);var r=0;return function(){return r>=t.length?{done:!0}:{done:!1,value:t[r++]}}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}(r);!(n=u()).done;){var f=n.value;e.containers[f]instanceof Promise&&(o.push(f),i.push(e.containers[f]))}var a={};return r.forEach(function(t){a[t]=e.containers[t]}),Promise.resolve(Promise.all(i)).then(function(t){return o.forEach(function(n,e){a[n]=t[e]}),a})}catch(t){return Promise.reject(t)}},r=e,(o=[{key:"containers",get:function(){var t=this,n={},e=function(e){!function(t,n,e){Object.defineProperty(t,n,{get:function(){return e()},enumerable:!0})}(n,e,function(){return t.get(e)})};for(var r in this.getTokens())e(r);return n}}])&&function(t,n){for(var e=0;e<n.length;e++){var r=n[e];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(t,r.key,r)}}(r.prototype,o),Object.defineProperty(r,"prototype",{writable:!1}),e}(h);t.NodeApi=p,t.makeRoot=function(){return new p}}); | ||
//# sourceMappingURL=iti.umd.js.map |
@@ -39,3 +39,3 @@ import { Intersection } from "utility-types"; | ||
protected _updateContext(updatedContext: Context): void; | ||
subscribeToContiner<T extends keyof Context>(token: T, cb: (container: UnpackFunction<Context[T]>) => void): () => void; | ||
subscribeToContiner<T extends keyof Context>(token: T, cb: (err: any, container: UnpackFunction<Context[T]>) => void): () => void; | ||
getTokens(): { | ||
@@ -59,3 +59,3 @@ [T in keyof Context]: T; | ||
_extractTokens<T extends keyof Context>(tokensOrCb: KeysOrCb<Context>): T[]; | ||
subscribeToContinerSet<T extends keyof Context>(tokensOrCb: KeysOrCb<Context>, cb: (container: { | ||
subscribeToContinerSet<T extends keyof Context>(tokensOrCb: KeysOrCb<Context>, cb: (err: any, container: { | ||
[K in T]: FullyUnpackObject<Context>[K]; | ||
@@ -62,0 +62,0 @@ }) => void): () => void; |
{ | ||
"name": "iti", | ||
"version": "0.3.1-alpha", | ||
"version": "0.4.0-next.0", | ||
"description": "~1kB inversion of control container for Typescript/Javascrith with a focus on async flow", | ||
@@ -28,6 +28,6 @@ "type": "module", | ||
"devDependencies": { | ||
"@testing-library/react": "^12.1.2", | ||
"@testing-library/react": "^12.1.4", | ||
"@testing-library/react-hooks": "^7.0.2", | ||
"@types/jest": "^27.4.0", | ||
"@types/react": "^17.0.38", | ||
"@types/jest": "^27.4.1", | ||
"@types/react": "^17.0.40", | ||
"jest": "^27.4.7", | ||
@@ -38,3 +38,3 @@ "microbundle": "^0.14.2", | ||
"tsd": "^0.19.1", | ||
"typescript": "^4.5.5" | ||
"typescript": "^4.6.2" | ||
}, | ||
@@ -41,0 +41,0 @@ "engines": { |
210
README.md
@@ -1,71 +0,68 @@ | ||
<a href="https://www.npmjs.org/package/iti"><img src="https://img.shields.io/npm/v/iti.svg" alt="npm"></a> | ||
![CI](https://github.com/molszanski/iti/actions/workflows/lib-test.yml/badge.svg) | ||
<a href="https://unpkg.com/iti/dist/iti.modern.js"><img src="https://img.badgesize.io/https://unpkg.com/iti/dist/iti.modern.js?compression=gzip" alt="gzip size"></a> | ||
# Iti [![CI status][ci-img]][ci-url] [![Gzip][gzip-img]][gzip-url] [![npm version][npm-img]][npm-url] | ||
🚧 **library is in beta mode** 🚧 | ||
[gzip-url]: https://unpkg.com/iti/dist/iti.modern.js | ||
[gzip-img]: https://img.badgesize.io/https://unpkg.com/iti/dist/iti.modern.js?compression=gzip | ||
[ci-url]: https://github.com/molszanski/iti/actions?query=branch%3Amaster | ||
[ci-img]: https://github.com/molszanski/iti/actions/workflows/lib-test.yml/badge.svg | ||
[npm-url]: https://www.npmjs.org/package/iti | ||
[npm-img]: https://img.shields.io/npm/v/iti.svg | ||
# Iti | ||
> 1kB inversion of control container for Typescript and Javascript with a unique feature that supports **async flow** | ||
> ~1kB inversion of control container for Typescript/Javascript for constructor injection with a focus on async flow | ||
- **fully async:** merges async code and a constructor injection via async functions (asynchronous factory pattern) | ||
- **non-invasive:** does not require library `@decorators` or framework `extends` in your application logic | ||
- **supports async(!):** merges async code and constructor injection via plain **async** functions | ||
- **non-invasive:** does not require imported `@decorators` or framework `extends` in your application business logic | ||
- **strongly typed:** has great IDE autocomplete and compile time check. Without any [manual type casting](https://github.com/inversify/InversifyJS/blob/master/wiki/container_api.md#containergettserviceidentifier-interfacesserviceidentifiert-t) | ||
- **lazy:** initialises your app modules and containers on demand | ||
- **split chunks:** enables [dynamic imports](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import#dynamic_imports) via a [one liner](#dynamic-imports) thanks to a fully async core | ||
- **Strongly typed:** With great IDE autocomplete and compile tme check. Works without [manual type casting](https://github.com/inversify/InversifyJS/blob/master/wiki/container_api.md#containergettserviceidentifier-interfacesserviceidentifiert-t) | ||
- **lightweight:** doesn't rely on `reflect-metadata` or decorators | ||
- **starter friendly:** works with starters like [Create React App](https://create-React-app.dev/) or [Next.js](https://nextjs.org/docs/getting-started) unlike [InversifyJS](https://github.com/inversify/InversifyJS) or [microsoft/tsyringe](https://github.com/microsoft/tsyringe) | ||
- **no Babel config:** it doesn't require `reflect-metadata` or decorators so there are no need to hack in decorator and `"decoratorMetadata"` support into Create React App, node.js, next.js, snowpack, esbuild etc. | ||
- **React support:** has useful React bindings to help separate application logic and React view layer | ||
- **tiny:** less than 2kB | ||
- **split chunks:** enables **[dynamic imports](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import#dynamic_imports)** via a [one liner](#dynamic-imports) thanks to a fully async core | ||
- **React friendly:** has useful **[React](https://github.com/molszanski/iti/tree/master/iti-react)** bindings to help you separate application business logic and a React view layer | ||
- **starter friendly:** works with starters like [Create React App](https://create-React-app.dev/) or [Next.js](https://nextjs.org/docs/getting-started) unlike existing libraries | ||
- **no Babel config:** doesn't require `reflect-metadata` or decorators so there is no need to hack in decorator and `"decoratorMetadata"` support in to your build configs | ||
- **tiny:** less than 1kB | ||
`iti` is an alternative to [InversifyJS](https://github.com/inversify/InversifyJS) and [microsoft/tsyringe](https://github.com/microsoft/tsyringe). It relies on plain JS functions, objects and familiar patterns. There is no need to learn complex API to use it in a full capacity. | ||
IoC is an amazing pattern and it should **easy to adopt**, fully support async and without hard to learn APIs or complex tooling requirements. | ||
## Usage | ||
Iti relies on plain JS functions, objects and familiar patterns. API is simple so you can make a **proof of concept integration in minutes**. | ||
``` | ||
npm install -S iti | ||
``` | ||
It is an alternative to [InversifyJS](https://github.com/inversify/InversifyJS) and [microsoft/tsyringe](https://github.com/microsoft/tsyringe) for constructor injection. | ||
### Basic Usage | ||
> _At [Packhelp](https://unpacked.packhelp.com) we’ve refactored most of our 65K SLOC Editor app, that didn't have any IoC, to Iti in under 5 hours_ | ||
```tsx | ||
// Step 1: Your application logic stays clean | ||
class Oven { | ||
## Usage | ||
```ts | ||
// kitchen.ts | ||
export class Oven { | ||
public pizzasInOven() { | ||
return 3 | ||
return 7 | ||
} | ||
public async preheat() {} | ||
} | ||
class Kitchen { | ||
constructor(public oven: Oven, public manual: string) {} | ||
export class Kitchen { | ||
constructor(public oven: Oven, public userManual: string) {} | ||
} | ||
// Application code is free of framework dependencies of decorators | ||
``` | ||
// Step 2: Add and read simple tokens | ||
```tsx | ||
// app.ts | ||
import { makeRoot } from "iti" | ||
let root = makeRoot().add({ | ||
userManual: "Please preheat before use", | ||
oven: () => new Oven(), | ||
}) | ||
root.get("oven") | ||
import { Oven, Kitchen } from "./kitchen" | ||
// Step 3: Add a usefull async provider / container | ||
const kitchenContainer = async ({ oven, userManual }) => { | ||
await oven.preheat() | ||
return { | ||
kitchen: new Kitchen(oven, userManual), | ||
} | ||
} | ||
// Step 4: Add an async provider | ||
const node = root.add((containers, node) => ({ | ||
kitchen: async () => | ||
kitchenContainer(await node.getContainerSet(["userManual", "oven"])), | ||
})) | ||
root.get("oven") // Oven | ||
await node.get("kitchen") // { kitchen: Kitchen } | ||
const node = makeRoot() | ||
.add({ | ||
oven: () => new Oven(), | ||
userManual: async () => "Please preheat before use", | ||
}) | ||
.add((ctx) => ({ | ||
kitchen: async () => new Kitchen(ctx.oven, await ctx.userManual), | ||
})) | ||
// Typical React usage | ||
await node.get("kitchen") // Kitchen | ||
``` | ||
```tsx | ||
// MyPizzaComponent.tsx | ||
export const PizzaData = () => { | ||
const [oven] = useContainer().oven | ||
return <> Pizzaz In Oven: {oven.pizzasInOven()}</> | ||
const kitchen = useContainer().kitchen | ||
return <>Pizzaz In Oven: {kitchen.oven.pizzasInOven()}</> | ||
} | ||
@@ -76,7 +73,7 @@ ``` | ||
Libraries like InversifyJS or tsyringe rely on decorators and `reflect-metadata`. | ||
The main reason is that existing libraries don’t support **asynchronous code**. Iti brings hassle free and fully typed way to use async code. | ||
Firstly, decorators unnecessary couple your application logic with a framework. | ||
Secondly, existing libraries rely on decorators and `reflect-metadata`[^1]. They **couple your application business logic with a single framework** and they tend to become unnecessarily complex. Also existing implementations will likely be incompatible with a [TC39 proposal](https://github.com/tc39/proposal-decorators). | ||
Secondly, it is very hard to use with starters like CRA, Next.js etc. To use `reflect-metadata` you need to configure your compiler (babel, typescrip, esbuild, swc etc.) configuratoin which is not trivial. So if you can’t use `reflect-metadata` you can't use inversify. | ||
Also it is hard to use `reflect-metadata` with starters like CRA, Next.js etc. You need to `eject` or hack starters and it is far from ideal. | ||
@@ -138,31 +135,20 @@ ## Short Manual | ||
### Single Instance (a.k.a. Singleton) | ||
### Lifecycle | ||
**Single Instance (a.k.a. Singleton)** | ||
```ts | ||
import { Oven, Kitchen } from "./kitchen/" | ||
export async function provideKitchenContainer() { | ||
const oven = new Oven() | ||
await oven.preheat() | ||
return { | ||
kitchen: new Kitchen(), | ||
oven: oven, | ||
} | ||
} | ||
let node = makeRoot().add({ | ||
oven: () => new Oven(), | ||
}) | ||
node.get("oven") === node.get("oven") // true | ||
``` | ||
### Transient | ||
**Transient** | ||
```ts | ||
import { Oven, Kitchen } from "./kitchen/" | ||
export async function provideKitchenContainer() { | ||
return { | ||
kitchen: () => new Kitchen(), | ||
oven: async () => { | ||
const oven = new Oven() | ||
await oven.preheat() | ||
return oven | ||
}, | ||
} | ||
} | ||
let node = makeRoot().add({ | ||
oven: () => () => new Oven(), | ||
}) | ||
node.get("oven") === node.get("oven") // false | ||
``` | ||
@@ -173,2 +159,3 @@ | ||
```ts | ||
// ./kitchen/index.ts | ||
export async function provideKitchenContainer() { | ||
@@ -188,5 +175,20 @@ const { Kitchen } = await import("./kitchen/kitchen") | ||
```ts | ||
// ./index.ts | ||
import { makeRoot } from "iti" | ||
import { provideKitchenContainer } from "./kitchen" | ||
let node = makeRoot().add({ | ||
kitchen: async () => provideKitchenContainer(), | ||
}) | ||
// Next line will load `./kitchen/kitchen` module | ||
await node.containers.kitchen | ||
// Next line will load `./kitchen/oven` module | ||
await node.containers.kitchen.oven | ||
``` | ||
### Tip: Prefer callbacks over of strings (in progress) | ||
If you use callback pattern across your app, you will be able to mass rename your containerKeys using typescript. With strings, you will have to manually go through the app. On the bright side, compiler will not compile until you fix your rename manually across the app. | ||
If you use callback pattern across your app, you will be able to mass rename your containerKeys using typescript. With strings, you will have to manually go through the app. But even if you use string literals compiler will not compile until you fix your rename manually across the app. | ||
@@ -203,17 +205,6 @@ ```ts | ||
### Tip: Prefer sealing your node | ||
## Anti Patterns | ||
This will help resolve some very exotic race conditions with subscriptions and container updates. We internally `seal()` our node on every `get` request but you can do it too before non trivial operations | ||
in progress | ||
```ts | ||
await makeRoot() | ||
.addPromise(async () => ({ | ||
a: "A", | ||
b: "B", | ||
})) | ||
.seal() // Good | ||
``` | ||
## Anti Patterns | ||
## Getting Started | ||
@@ -234,4 +225,3 @@ | ||
export function getMainMockAppContainer() { | ||
let node = makeRoot() | ||
let k = node | ||
return makeRoot() | ||
.add({ aCont: async () => provideAContainer() }) | ||
@@ -248,3 +238,2 @@ .add((containers) => { | ||
}) | ||
return k | ||
} | ||
@@ -309,6 +298,5 @@ ``` | ||
```ts | ||
import { makeRoot, RootContainer } from "../../library.root-container" | ||
import { makeRoot } from "../../library.root-container" | ||
export function getMainMockAppContainer() { | ||
// check get providers above | ||
return makeRoot(getProviders) | ||
return makeRoot().add({ kitchen: () => new Kitchen(/* deps */) }) | ||
} | ||
@@ -333,7 +321,27 @@ ``` | ||
# Alternaitves | ||
## No async support | ||
Existing libraries like inversify and others don’t support asynchronous code. | ||
They either provide a promise to your constructor or require one to imperatively execute all potentially async code before the binding phase. | ||
This is far from ideal. | ||
## Heavy use of decorators | ||
Secondly, they rely on decorators and `reflect-metadata` | ||
Decorators create unnecessary coupling of an application business logic with a framework. The whole idea of DI is to decouple the application business logic. Coupling classes with a DI framework is still coupling and turns DI into a service locator. | ||
Also, decorator support is an experimental feature in Typescript and current implementation is not compatible with the TC39 proposal. This will probably cause problems for any non-trivial decorators and babel hacks. | ||
In addition to that it is very hard to use `reflect-metadata` with starters like CRA, Next.js etc. To use `reflect-metadata` you need to tweak your compilers (babel, typescript, esbuild, swc etc.) configuration. So if you can’t use `reflect-metadata` you can’t use `inversify` or `tsyringe`. | ||
## Comparison with `inversifyjs`, `tsyringe` and others | ||
Inversion of Control (IoC) is a great way to decouple the application and the most popular pattern of IoC is dependency injection (DI) [but it is not limited to one](https://martinfowler.com/articles/injection.html). | ||
Inversion of Control (IoC) is a great way to decouple code and the most popular pattern of IoC is dependency injection (DI) [but it is not limited to one](https://martinfowler.com/articles/injection.html). | ||
In JavaScript there is not way to create a dependency injection without mixing application logic with a specific IoC library code or hacking a compiler (reflect-metadata). | ||
In JavaScript there is not way to create a dependency injection without mixing application business logic with a specific IoC library code or hacking a compiler (reflect-metadata). | ||
@@ -374,3 +382,3 @@ **`inversifyjs` and `tsyringe` use decorators and `reflect-metada`** | ||
With Iti your application logic is not mixed with the framework code | ||
With Iti your application business logic is not mixed with the framework code | ||
@@ -420,1 +428,3 @@ ```ts | ||
This is temporary(?) limitation to keep typescript happy and typescript types reasonable sane | ||
[^1]: Kudos to [typed-inject](https://github.com/nicojs/typed-inject) for finding a reasonable alternative to decorators and Reflect. Sadly, it doesn't support async and there are some other limits |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
106270
319
420