Comparing version 1.2.0 to 1.3.0
/** | ||
* This module has been designed to be a drop-in replacement for extending built-in elements. It is supposed to be | ||
* 1. More widely supported. Safari does not support 'is' attribute. | ||
* 2. More concise and flexible. You can register and unregister components and you can attach multiple components to the same element.. | ||
* 3. Easier to pass down props in markup without creating ugly markup. | ||
* Actributes lets you attach components to HTML elements within markup. 2 | ||
* use cases we have found include implementing reactivity (Actribution) and | ||
* 'extending' built-in elements. | ||
* | ||
* The attributes here name the components and the values | ||
* are the names of props to pass to them along with the element. | ||
* The attributes here name the components and any values | ||
* are passed to the components along with the element. Components can use the | ||
* values in any appropriate to their operations. Simple components will typically | ||
* call the props function on them to extract properties from objects which they | ||
* then use for their operation. More complex components could interprete the values | ||
* as code. | ||
* | ||
* @example | ||
* import { Actribute } from 'deleight/actribute'; | ||
* import { Actribute, props } from 'deleight/actribute'; | ||
* // initialize: | ||
@@ -17,10 +20,10 @@ * const fallbackProps = { | ||
* }; | ||
* const act = new Actribute(fallbackProps); | ||
* const act = new Actribute(); | ||
* | ||
* // register components: | ||
* act.register('comp1', (node, prop1) => node.textContent = prop1); | ||
* act.register('comp2', (node, prop2) => node.style.left = prop2); | ||
* act.register('comp1', (element, attr, ...context) => element.textContent = props(attr.value, context)[0]); | ||
* act.register('comp2', (element, attr) => element.style.left = attr.value); | ||
* | ||
* // use in markup: | ||
* // <section c-comp1="prop1" c-comp2="prop2" > | ||
* // <section c-comp1="prop1" c-comp2="100px" > | ||
* // First section | ||
@@ -30,3 +33,3 @@ * // </section> | ||
* / process components: | ||
* act.process(document.body, {prop2: 1, prop3: 2}); | ||
* act.process({el: document.body, ctx: [{prop1: 2, prop3: 2}, fallbackProps]}); | ||
* | ||
@@ -38,7 +41,7 @@ * // unregister a component: | ||
* Represents a component function. The function takes an element | ||
* as its first argument. It may optionally receive further props | ||
* arguments. It can return anything. | ||
* as its first argument and the attribute as its second argument. It may | ||
* optionally receive further context arguments. It can return anything. | ||
*/ | ||
interface IComponent { | ||
(element: Element, ...props: any[]): any; | ||
(element: Element, attr: Attr, ...context: any[]): any; | ||
} | ||
@@ -53,4 +56,13 @@ /** | ||
} | ||
interface IActributeInit { | ||
open?: string; | ||
closed?: string; | ||
} | ||
type IProcessOptions = { | ||
el?: Element; | ||
attr?: string; | ||
ctx?: any[]; | ||
} | Element | string | any[]; | ||
/** | ||
* An Actribute class. Similar to a custom elements registry 'class'. | ||
* An Actribute class. This is almost like a custom elements registry 'class'. | ||
*/ | ||
@@ -66,22 +78,14 @@ declare class Actribute { | ||
/** | ||
* This object holds any fallback props which can be referenced | ||
* in the markup, in the values of component attributes. Property names | ||
* can be referenced similarly to CSS classes. | ||
* The attribute used to specify that the tree of an element with | ||
* components is open to nested processing. | ||
*/ | ||
props: any; | ||
openAttr: string; | ||
/** | ||
* This is the attribute prefix that denotes component specifiers in | ||
* markup. A component specifier is an attribute where the name (after | ||
* the prefix) refers to a component name (in the registery) and the | ||
* optional value is a space-separated list of property names. | ||
* The attribute used to specify that the tree of an element with | ||
* components is not open to nested processing. | ||
*/ | ||
attrPrefix: string; | ||
closedAttr: string; | ||
/** | ||
* Construct a new Actribute instance with the fallback props and | ||
* attribute prefix. | ||
* Construct a new Actribute instance. | ||
* | ||
* It is similar to a Custom Element registry. When used to process | ||
* markup, attributes with names starting with `attrPrefix` are treated | ||
* as component specifiers. | ||
* | ||
* A component specifier is of the form [attrPrefix][componentName]="[propertyName] [propertyName] ..." | ||
@@ -106,14 +110,10 @@ * | ||
* | ||
* @param {any} props The value to assign to the props member. | ||
* @param {string} attrPrefix The value to assign to attrPrefix. Defaults to 'c-' | ||
* @param {IActributeInit} init The value to assign to attrPrefix. Defaults to 'c-' | ||
* @constructor | ||
*/ | ||
constructor(props: any, attrPrefix: string); | ||
constructor(init?: IActributeInit); | ||
/** | ||
* Registers a function as a component bearing the given name. | ||
* The component can be referenced in processed markup using | ||
* the name. | ||
* Registers multiple components at once using an object that maps | ||
* component names to component functions. | ||
* | ||
* Returns the same actribute to support chaining. | ||
* | ||
* @example | ||
@@ -125,21 +125,3 @@ * import { Actribute } from 'deleight/actribute'; | ||
* const act = new Actribute(fallbackProps); | ||
* act.register('comp1', (element, prop1) => element.textContent = prop1); | ||
* act.register('comp2', (element, prop2) => element.style.left = prop2); | ||
* | ||
* @param {string} name The component name | ||
* @param {Function} component The component function | ||
* @returns {Actribute} | ||
*/ | ||
register(name: string, component: IComponent): Actribute; | ||
/** | ||
* Registers multiple components at once using an object that maps | ||
* component names to component functions. This is more succint than | ||
* repeated calls to `this.register()`. | ||
* @example | ||
* import { Actribute } from 'deleight/actribute'; | ||
* const fallbackProps = { | ||
* prop1: 'Fallback', prop4: 'Last resort' | ||
* }; | ||
* const act = new Actribute(fallbackProps); | ||
* act.registerAll({ | ||
* act.register({ | ||
* comp1: (element, prop1) => element.textContent = prop1, | ||
@@ -152,33 +134,49 @@ * comp2: (element, prop2) => element.style.left = prop2 | ||
*/ | ||
registerAll(registerMap: IRegisterMap): this; | ||
register(registerMap: IRegisterMap): this; | ||
/** | ||
* Recursively processes the node to identify and apply components. | ||
* Recursively processes `options.el` (or `document.body` by default) to | ||
* identify and apply components. Attributes with names starting with | ||
* `options.attr` (or `c-` by default) are treated as component specifiers. | ||
* | ||
* At elements where any components are encountered, the components | ||
* are called with the element and any specified props. The decendants | ||
* are not processed. | ||
* are called with the element, the attribute value and any specified | ||
* context objects (`...(options.context || [])`). | ||
* | ||
* At elements without a component, the descendants are processed | ||
* recursively. | ||
* Where a component is encountered, decendants are not processed unless `this.open` | ||
* attribute is present on the element. At elements without a component, the descendants | ||
* are processed recursively, except `this.closed` boolean attribute is | ||
* specified. These are supposed to echo the semantics of the Shadow DOM API. | ||
* | ||
* If a component is not found and a wild-card component is registered (with '*'), | ||
* the widcard component is called instead with the whole attribute passed as the second | ||
* argument. | ||
* | ||
* Returns the same actribute to support call chaining. | ||
* | ||
* @example | ||
* import { Actribute } from 'deleight/actribute'; | ||
* const fallbackProps = { | ||
* prop1: 'Fallback', prop4: 'Last resort' | ||
* }; | ||
* const act = new Actribute(fallbackProps); | ||
* act.register('comp1', (node, prop1) => node.textContent = prop1); | ||
* act.register('comp2', (node, prop2) => node.style.left = prop2); | ||
* act.process(document.body, {prop2: 1, prop3: 2}); | ||
* import { Actribute, props } from 'deleight/actribute'; | ||
* const act = new Actribute(); | ||
* act.register({ | ||
* comp1: (element, attr, singleContext) => element.textContent = attr.value, | ||
* comp2: (element, attr, singleContext) => element.style.left = props(attr.value, [singleContext]) | ||
* }); | ||
* act.process([{prop2: 1, prop3: 2}]); | ||
* | ||
* @param {HTMLElement} element | ||
* @param {any} [props] | ||
* @param {string} [propSep] | ||
* @param {IProcessOptions} [options] | ||
* @returns {Actribute} | ||
*/ | ||
process(element: Element, props?: any, propSep?: string): Actribute; | ||
process(options?: IProcessOptions): Actribute; | ||
} | ||
/** | ||
* Obtain properties from the specified sources. Specify the property names | ||
* separated by a separator (`" "` by default). | ||
* @example | ||
* | ||
* @param names | ||
* @param sources | ||
* @param sep | ||
* @returns | ||
*/ | ||
declare function props(names: string, sources: any[], sep?: string): any[]; | ||
export { Actribute, type IRegisterMap }; | ||
export { Actribute, type IActributeInit, type IComponent, type IProcessOptions, type IRegisterMap, props }; |
@@ -1,1 +0,1 @@ | ||
"use strict";function t(t,r){const e=r.split(".");let i=t[e[0].trim()];for(let r=1;r<e.length&&("object"==typeof i||"function"==typeof i);r++)i=(t=i)[e[r].trim()];return i}exports.Actribute=class{registry={};props;attrPrefix;constructor(t,r){this.props=t||{},this.attrPrefix=r||"c-"}register(t,r){return(this.registry[t]=r)&&this}registerAll(t){return Object.assign(this.registry,t)&&this}process(r,e,i){e||(e={}),void 0===i&&(i=" ");let s,o,n,f=[],h=!1;for(let{name:p,value:c}of Array.from(r.attributes))if(p.startsWith(this.attrPrefix)){if(h=!0,s=p.substring(this.attrPrefix.length),!this.registry.hasOwnProperty(s))throw new Error(`The component "${s}" was not found in the registry.`);if(f=[],c=c.trim(),c)for(o of c.split(i))if(o=o.trim(),""!==o){if(n=t(e,o)||t(this.props,o),void 0===n)throw new Error(`The property "${o}" was not found for the component "${s}" in the element "${r.toString()}"."`);f.push(n)}this.registry[s](r,...f)}if(!h)for(let t of Array.from(r.children))this.process(t,e,i);return this}}; | ||
"use strict";function t(t,r){const e=r.split(".");let s=t[e[0].trim()];for(let r=1;r<e.length&&("object"==typeof s||"function"==typeof s);r++)s=(t=s)[e[r].trim()];return s}exports.Actribute=class{registry={};openAttr;closedAttr;constructor(t){this.openAttr=t?.open||"o-pen",this.closedAttr=t?.closed||"c-losed"}register(t){return Object.assign(this.registry,t)&&this}process(t){let r,e,s;"string"==typeof t?e=t:t instanceof Element?r=t:t instanceof Array?s=t:"object"==typeof t&&(r=t.el,e=t.attr,s=t.ctx),r||(r=document.body),e||(e="c-"),s||(s=[]);const o=r.attributes,i=o.length;let n,c,h,f=!1,p=r.hasAttribute(this.openAttr);for(c=0;c<i;c++)if(n=o[c],n.name.startsWith(e))if(f=!0,h=n.name.substring(e.length),this.registry.hasOwnProperty(h))this.registry[h](r,n,...s);else{if(!this.registry.hasOwnProperty("*"))throw new Error(`The component "${h}" was not found in the registry.`);this.registry["*"](r,n,...s)}if(!f||p)for(let t of Array.from(r.children))t.hasAttribute(this.closedAttr)||this.process({el:t,attr:e,ctx:s});return this}},exports.props=function(r,e,s){const o=[],i=e.length;let n,c,h;for(n of(r=r.trim()).split(s||" "))if(n=n.trim(),""!==n){for(c=void 0,h=-1;void 0===c&&++h<i;)c=t(e[h],n);if(void 0===c)throw new TypeError(`The property "${n}" was not found in any of the sources.`);o.push(c)}return o}; |
/** | ||
* This module has been designed to be a drop-in replacement for extending built-in elements. It is supposed to be | ||
* 1. More widely supported. Safari does not support 'is' attribute. | ||
* 2. More concise and flexible. You can register and unregister components and you can attach multiple components to the same element.. | ||
* 3. Easier to pass down props in markup without creating ugly markup. | ||
* Actributes lets you attach components to HTML elements within markup. 2 | ||
* use cases we have found include implementing reactivity (Actribution) and | ||
* 'extending' built-in elements. | ||
* | ||
* The attributes here name the components and the values | ||
* are the names of props to pass to them along with the element. | ||
* The attributes here name the components and any values | ||
* are passed to the components along with the element. Components can use the | ||
* values in any appropriate to their operations. Simple components will typically | ||
* call the props function on them to extract properties from objects which they | ||
* then use for their operation. More complex components could interprete the values | ||
* as code. | ||
* | ||
* @example | ||
* import { Actribute } from 'deleight/actribute'; | ||
* import { Actribute, props } from 'deleight/actribute'; | ||
* // initialize: | ||
@@ -17,10 +20,10 @@ * const fallbackProps = { | ||
* }; | ||
* const act = new Actribute(fallbackProps); | ||
* const act = new Actribute(); | ||
* | ||
* // register components: | ||
* act.register('comp1', (node, prop1) => node.textContent = prop1); | ||
* act.register('comp2', (node, prop2) => node.style.left = prop2); | ||
* act.register('comp1', (element, attr, ...context) => element.textContent = props(attr.value, context)[0]); | ||
* act.register('comp2', (element, attr) => element.style.left = attr.value); | ||
* | ||
* // use in markup: | ||
* // <section c-comp1="prop1" c-comp2="prop2" > | ||
* // <section c-comp1="prop1" c-comp2="100px" > | ||
* // First section | ||
@@ -30,3 +33,3 @@ * // </section> | ||
* / process components: | ||
* act.process(document.body, {prop2: 1, prop3: 2}); | ||
* act.process({el: document.body, ctx: [{prop1: 2, prop3: 2}, fallbackProps]}); | ||
* | ||
@@ -38,7 +41,7 @@ * // unregister a component: | ||
* Represents a component function. The function takes an element | ||
* as its first argument. It may optionally receive further props | ||
* arguments. It can return anything. | ||
* as its first argument and the attribute as its second argument. It may | ||
* optionally receive further context arguments. It can return anything. | ||
*/ | ||
interface IComponent { | ||
(element: Element, ...props: any[]): any; | ||
(element: Element, attr: Attr, ...context: any[]): any; | ||
} | ||
@@ -53,4 +56,13 @@ /** | ||
} | ||
interface IActributeInit { | ||
open?: string; | ||
closed?: string; | ||
} | ||
type IProcessOptions = { | ||
el?: Element; | ||
attr?: string; | ||
ctx?: any[]; | ||
} | Element | string | any[]; | ||
/** | ||
* An Actribute class. Similar to a custom elements registry 'class'. | ||
* An Actribute class. This is almost like a custom elements registry 'class'. | ||
*/ | ||
@@ -66,22 +78,14 @@ declare class Actribute { | ||
/** | ||
* This object holds any fallback props which can be referenced | ||
* in the markup, in the values of component attributes. Property names | ||
* can be referenced similarly to CSS classes. | ||
* The attribute used to specify that the tree of an element with | ||
* components is open to nested processing. | ||
*/ | ||
props: any; | ||
openAttr: string; | ||
/** | ||
* This is the attribute prefix that denotes component specifiers in | ||
* markup. A component specifier is an attribute where the name (after | ||
* the prefix) refers to a component name (in the registery) and the | ||
* optional value is a space-separated list of property names. | ||
* The attribute used to specify that the tree of an element with | ||
* components is not open to nested processing. | ||
*/ | ||
attrPrefix: string; | ||
closedAttr: string; | ||
/** | ||
* Construct a new Actribute instance with the fallback props and | ||
* attribute prefix. | ||
* Construct a new Actribute instance. | ||
* | ||
* It is similar to a Custom Element registry. When used to process | ||
* markup, attributes with names starting with `attrPrefix` are treated | ||
* as component specifiers. | ||
* | ||
* A component specifier is of the form [attrPrefix][componentName]="[propertyName] [propertyName] ..." | ||
@@ -106,14 +110,10 @@ * | ||
* | ||
* @param {any} props The value to assign to the props member. | ||
* @param {string} attrPrefix The value to assign to attrPrefix. Defaults to 'c-' | ||
* @param {IActributeInit} init The value to assign to attrPrefix. Defaults to 'c-' | ||
* @constructor | ||
*/ | ||
constructor(props: any, attrPrefix: string); | ||
constructor(init?: IActributeInit); | ||
/** | ||
* Registers a function as a component bearing the given name. | ||
* The component can be referenced in processed markup using | ||
* the name. | ||
* Registers multiple components at once using an object that maps | ||
* component names to component functions. | ||
* | ||
* Returns the same actribute to support chaining. | ||
* | ||
* @example | ||
@@ -125,21 +125,3 @@ * import { Actribute } from 'deleight/actribute'; | ||
* const act = new Actribute(fallbackProps); | ||
* act.register('comp1', (element, prop1) => element.textContent = prop1); | ||
* act.register('comp2', (element, prop2) => element.style.left = prop2); | ||
* | ||
* @param {string} name The component name | ||
* @param {Function} component The component function | ||
* @returns {Actribute} | ||
*/ | ||
register(name: string, component: IComponent): Actribute; | ||
/** | ||
* Registers multiple components at once using an object that maps | ||
* component names to component functions. This is more succint than | ||
* repeated calls to `this.register()`. | ||
* @example | ||
* import { Actribute } from 'deleight/actribute'; | ||
* const fallbackProps = { | ||
* prop1: 'Fallback', prop4: 'Last resort' | ||
* }; | ||
* const act = new Actribute(fallbackProps); | ||
* act.registerAll({ | ||
* act.register({ | ||
* comp1: (element, prop1) => element.textContent = prop1, | ||
@@ -152,33 +134,49 @@ * comp2: (element, prop2) => element.style.left = prop2 | ||
*/ | ||
registerAll(registerMap: IRegisterMap): this; | ||
register(registerMap: IRegisterMap): this; | ||
/** | ||
* Recursively processes the node to identify and apply components. | ||
* Recursively processes `options.el` (or `document.body` by default) to | ||
* identify and apply components. Attributes with names starting with | ||
* `options.attr` (or `c-` by default) are treated as component specifiers. | ||
* | ||
* At elements where any components are encountered, the components | ||
* are called with the element and any specified props. The decendants | ||
* are not processed. | ||
* are called with the element, the attribute value and any specified | ||
* context objects (`...(options.context || [])`). | ||
* | ||
* At elements without a component, the descendants are processed | ||
* recursively. | ||
* Where a component is encountered, decendants are not processed unless `this.open` | ||
* attribute is present on the element. At elements without a component, the descendants | ||
* are processed recursively, except `this.closed` boolean attribute is | ||
* specified. These are supposed to echo the semantics of the Shadow DOM API. | ||
* | ||
* If a component is not found and a wild-card component is registered (with '*'), | ||
* the widcard component is called instead with the whole attribute passed as the second | ||
* argument. | ||
* | ||
* Returns the same actribute to support call chaining. | ||
* | ||
* @example | ||
* import { Actribute } from 'deleight/actribute'; | ||
* const fallbackProps = { | ||
* prop1: 'Fallback', prop4: 'Last resort' | ||
* }; | ||
* const act = new Actribute(fallbackProps); | ||
* act.register('comp1', (node, prop1) => node.textContent = prop1); | ||
* act.register('comp2', (node, prop2) => node.style.left = prop2); | ||
* act.process(document.body, {prop2: 1, prop3: 2}); | ||
* import { Actribute, props } from 'deleight/actribute'; | ||
* const act = new Actribute(); | ||
* act.register({ | ||
* comp1: (element, attr, singleContext) => element.textContent = attr.value, | ||
* comp2: (element, attr, singleContext) => element.style.left = props(attr.value, [singleContext]) | ||
* }); | ||
* act.process([{prop2: 1, prop3: 2}]); | ||
* | ||
* @param {HTMLElement} element | ||
* @param {any} [props] | ||
* @param {string} [propSep] | ||
* @param {IProcessOptions} [options] | ||
* @returns {Actribute} | ||
*/ | ||
process(element: Element, props?: any, propSep?: string): Actribute; | ||
process(options?: IProcessOptions): Actribute; | ||
} | ||
/** | ||
* Obtain properties from the specified sources. Specify the property names | ||
* separated by a separator (`" "` by default). | ||
* @example | ||
* | ||
* @param names | ||
* @param sources | ||
* @param sep | ||
* @returns | ||
*/ | ||
declare function props(names: string, sources: any[], sep?: string): any[]; | ||
export { Actribute, type IRegisterMap }; | ||
export { Actribute, type IActributeInit, type IComponent, type IProcessOptions, type IRegisterMap, props }; |
@@ -1,1 +0,1 @@ | ||
class t{registry={};props;attrPrefix;constructor(t,r){this.props=t||{},this.attrPrefix=r||"c-"}register(t,r){return(this.registry[t]=r)&&this}registerAll(t){return Object.assign(this.registry,t)&&this}process(t,e,i){e||(e={}),void 0===i&&(i=" ");let s,o,n,f=[],h=!1;for(let{name:p,value:a}of Array.from(t.attributes))if(p.startsWith(this.attrPrefix)){if(h=!0,s=p.substring(this.attrPrefix.length),!this.registry.hasOwnProperty(s))throw new Error(`The component "${s}" was not found in the registry.`);if(f=[],a=a.trim(),a)for(o of a.split(i))if(o=o.trim(),""!==o){if(n=r(e,o)||r(this.props,o),void 0===n)throw new Error(`The property "${o}" was not found for the component "${s}" in the element "${t.toString()}"."`);f.push(n)}this.registry[s](t,...f)}if(!h)for(let r of Array.from(t.children))this.process(r,e,i);return this}}function r(t,r){const e=r.split(".");let i=t[e[0].trim()];for(let r=1;r<e.length&&("object"==typeof i||"function"==typeof i);r++)i=(t=i)[e[r].trim()];return i}export{t as Actribute}; | ||
class t{registry={};openAttr;closedAttr;constructor(t){this.openAttr=t?.open||"o-pen",this.closedAttr=t?.closed||"c-losed"}register(t){return Object.assign(this.registry,t)&&this}process(t){let r,e,o;"string"==typeof t?e=t:t instanceof Element?r=t:t instanceof Array?o=t:"object"==typeof t&&(r=t.el,e=t.attr,o=t.ctx),r||(r=document.body),e||(e="c-"),o||(o=[]);const s=r.attributes,i=s.length;let n,h,c,f=!1,l=r.hasAttribute(this.openAttr);for(h=0;h<i;h++)if(n=s[h],n.name.startsWith(e))if(f=!0,c=n.name.substring(e.length),this.registry.hasOwnProperty(c))this.registry[c](r,n,...o);else{if(!this.registry.hasOwnProperty("*"))throw new Error(`The component "${c}" was not found in the registry.`);this.registry["*"](r,n,...o)}if(!f||l)for(let t of Array.from(r.children))t.hasAttribute(this.closedAttr)||this.process({el:t,attr:e,ctx:o});return this}}function r(t,r){const e=r.split(".");let o=t[e[0].trim()];for(let r=1;r<e.length&&("object"==typeof o||"function"==typeof o);r++)o=(t=o)[e[r].trim()];return o}function e(t,e,o){const s=[],i=e.length;let n,h,c;for(n of(t=t.trim()).split(o||" "))if(n=n.trim(),""!==n){for(h=void 0,c=-1;void 0===h&&++c<i;)h=r(e[c],n);if(void 0===h)throw new TypeError(`The property "${n}" was not found in any of the sources.`);s.push(h)}return s}export{t as Actribute,e as props}; |
@@ -28,6 +28,23 @@ /** | ||
* @param {any[]} [context] Shared context for the 'many' functions or object methods | ||
* @param {number} [mainItem] Set a main item (like 0 for the first item) if the one must behave | ||
* like it. This way the main item can be simply replaced with the one in existing code. | ||
* @returns | ||
*/ | ||
declare function one(many: any[], recursive?: boolean, context?: any[]): One; | ||
declare function one(many: any[], recursive?: boolean, context?: any[], mainItem?: number): One; | ||
/** | ||
* Return a wrapped (proxied) One from a pure One. | ||
* | ||
* @example | ||
* import { One, wrap } from 'deleight/onetomany'; | ||
* const o = new One([{a: 1}, {a: 2}]) | ||
* o.set('a', [4, 7]); | ||
* const a = wrap(o).a // [4, 7] | ||
* | ||
* @param o | ||
* @param {number} [mainItem] Set a main item (like 0 for the first item) if the one must behave | ||
* like it. This way the main item can be simply replaced with the one in existing code. | ||
* @returns | ||
*/ | ||
declare function wrap(o: One, mainItem?: number): One; | ||
/** | ||
* Return a 'pure' One from a proxied One. | ||
@@ -49,3 +66,3 @@ * | ||
interface IOneConstructor { | ||
(many: any[], recursive?: boolean, context?: any[], ctor?: IOneConstructor): One; | ||
(many: any[], recursive?: boolean, context?: any[]): One; | ||
} | ||
@@ -67,2 +84,7 @@ /** | ||
/** | ||
* Optionally set main item interpreted specially when the one is | ||
* proxied. | ||
*/ | ||
mainItem?: number; | ||
/** | ||
* Whether this One will return other 'One's in calls to `get`. | ||
@@ -88,4 +110,2 @@ */ | ||
* This is an array of objects passed as the final arguments in calls. Empty array by default. | ||
* @param {IOneConstructor} [ctor] The constructor used to create the `get` Ones. This parameter is used internally; | ||
* no need to supply an argument. | ||
* | ||
@@ -99,3 +119,3 @@ * @example | ||
*/ | ||
constructor(many: any[], recursive?: boolean, context?: any[], ctor?: IOneConstructor); | ||
constructor(many: any[], recursive?: boolean, context?: any[]); | ||
/** | ||
@@ -179,2 +199,2 @@ * Gets corresponding properties from all the objects in many. If this is | ||
export { type IOneConstructor, One, one, unWrap }; | ||
export { type IOneConstructor, One, one, unWrap, wrap }; |
@@ -1,1 +0,1 @@ | ||
"use strict";const t=Symbol();const e={get(e,s){if(s===t)return e;let r=e.get(s,!0);return r.length&&"function"==typeof r[0]?(...t)=>e.call(t,s):e.recursive?e.ctor?e.ctor(r,!0,e.context,e.ctor):new n(r,!0,e.context):r},set:(t,e,n)=>(t.set(e,n),!0)};class n{many;recursive;ctor;context;constructor(t,e,n,s){this.many=t,this.recursive=e,this.ctor=s,this.context=n||[]}get(t,e){const s=[],r=this.many.length;if(null!=t)for(let e=0;e<r;e++)s.push(this.many[e][t]);else for(let t=0;t<r;t++)s.push(this.many[t]);const i=[s,this.recursive,this.context];return this.recursive&&!e?this.ctor?this.ctor(...i,this.ctor):new n(...i):s}set(t,e){if(void 0===e)return this.set(t,this.get(t,!0));const n=this.many.length,s=e.length;if(null!=t)for(let r=0;r<n;r++)this.many[r][t]=e[Math.min(r,s-1)];else for(let t=0;t<n;t++)this.many[t]=e[Math.min(t,s-1)]}delete(t){for(let e of this.many)delete e[t]}call(t,e){void 0!==t&&t.length||(t=[[]]);const n=[],s=this.many.length,r=t.length;let i,o;if(void 0!==e)for(let h=0;h<s;h++)i=t[Math.min(h,r-1)]||[],o=this.many[h][e](...i,...this.context),n.push(o);else for(let e=0;e<s;e++)i=t[Math.min(e,r-1)]||[],o=this.many[e](...i,...this.context),n.push(o);return n}}exports.One=n,exports.one=function t(s,r,i){return new Proxy(new n(s,r,i,t),e)},exports.unWrap=function(e){return e[t]||e}; | ||
"use strict";function t(e,i,s,o){const c=new r(e,i,s);return c.ctor=t,void 0!==o&&(c.mainItem=o),new Proxy(c,n)}const e=Symbol();const n={get(t,n){if(n===e)return t;let i=t.get(n,!0);if(i.length&&"function"==typeof i[0])return void 0!==t.mainItem?(...e)=>t.call([e],n)[t.mainItem]:(...e)=>t.call(e,n);if(t.recursive){if(t.ctor){const n=t.ctor(i,!0,t.context);return(n[e]||n).ctor=t.ctor,n}return new r(i,!0,t.context)}return void 0!==t.mainItem?i[t.mainItem]:i},set:(t,e,n)=>(t.set(e,n),!0)};class r{many;mainItem;recursive;ctor;context;constructor(t,e,n){this.many=t,this.recursive=e,this.context=n||[]}get(t,n){const i=[],s=this.many.length;if(null!=t)for(let e=0;e<s;e++)i.push(this.many[e][t]);else for(let t=0;t<s;t++)i.push(this.many[t]);if(!this.recursive||n)return i;if(!this.ctor)return new r(i,this.recursive,this.context);{const t=this.ctor(i,this.recursive,this.context);(t[e]||t).ctor=this.ctor}}set(t,e){if(void 0===e)return this.set(t,this.get(t,!0));e instanceof Array||(e=[e]);const n=this.many.length,r=e.length;if(null!=t)for(let i=0;i<n;i++)this.many[i][t]=e[Math.min(i,r-1)];else for(let t=0;t<n;t++)this.many[t]=e[Math.min(t,r-1)]}delete(t){for(let e of this.many)delete e[t]}call(t,e){void 0!==t&&t.length||(t=[[]]);const n=[],r=this.many.length,i=t.length;let s,o;if(void 0!==e)for(let c=0;c<r;c++)s=t[Math.min(c,i-1)]||[],o=this.many[c][e](...s,...this.context),n.push(o);else for(let e=0;e<r;e++)s=t[Math.min(e,i-1)]||[],o=this.many[e](...s,...this.context),n.push(o);return n}}exports.One=r,exports.one=t,exports.unWrap=function(t){return t[e]||t},exports.wrap=function(e,r){return e.ctor=t,void 0!==r&&(e.mainItem=r),new Proxy(e,n)}; |
@@ -28,6 +28,23 @@ /** | ||
* @param {any[]} [context] Shared context for the 'many' functions or object methods | ||
* @param {number} [mainItem] Set a main item (like 0 for the first item) if the one must behave | ||
* like it. This way the main item can be simply replaced with the one in existing code. | ||
* @returns | ||
*/ | ||
declare function one(many: any[], recursive?: boolean, context?: any[]): One; | ||
declare function one(many: any[], recursive?: boolean, context?: any[], mainItem?: number): One; | ||
/** | ||
* Return a wrapped (proxied) One from a pure One. | ||
* | ||
* @example | ||
* import { One, wrap } from 'deleight/onetomany'; | ||
* const o = new One([{a: 1}, {a: 2}]) | ||
* o.set('a', [4, 7]); | ||
* const a = wrap(o).a // [4, 7] | ||
* | ||
* @param o | ||
* @param {number} [mainItem] Set a main item (like 0 for the first item) if the one must behave | ||
* like it. This way the main item can be simply replaced with the one in existing code. | ||
* @returns | ||
*/ | ||
declare function wrap(o: One, mainItem?: number): One; | ||
/** | ||
* Return a 'pure' One from a proxied One. | ||
@@ -49,3 +66,3 @@ * | ||
interface IOneConstructor { | ||
(many: any[], recursive?: boolean, context?: any[], ctor?: IOneConstructor): One; | ||
(many: any[], recursive?: boolean, context?: any[]): One; | ||
} | ||
@@ -67,2 +84,7 @@ /** | ||
/** | ||
* Optionally set main item interpreted specially when the one is | ||
* proxied. | ||
*/ | ||
mainItem?: number; | ||
/** | ||
* Whether this One will return other 'One's in calls to `get`. | ||
@@ -88,4 +110,2 @@ */ | ||
* This is an array of objects passed as the final arguments in calls. Empty array by default. | ||
* @param {IOneConstructor} [ctor] The constructor used to create the `get` Ones. This parameter is used internally; | ||
* no need to supply an argument. | ||
* | ||
@@ -99,3 +119,3 @@ * @example | ||
*/ | ||
constructor(many: any[], recursive?: boolean, context?: any[], ctor?: IOneConstructor); | ||
constructor(many: any[], recursive?: boolean, context?: any[]); | ||
/** | ||
@@ -179,2 +199,2 @@ * Gets corresponding properties from all the objects in many. If this is | ||
export { type IOneConstructor, One, one, unWrap }; | ||
export { type IOneConstructor, One, one, unWrap, wrap }; |
@@ -1,1 +0,1 @@ | ||
function t(e,n,r){return new Proxy(new i(e,n,r,t),s)}const e=Symbol();function n(t){return t[e]||t}const s={get(t,n){if(n===e)return t;let s=t.get(n,!0);return s.length&&"function"==typeof s[0]?(...e)=>t.call(e,n):t.recursive?t.ctor?t.ctor(s,!0,t.context,t.ctor):new i(s,!0,t.context):s},set:(t,e,n)=>(t.set(e,n),!0)};class i{many;recursive;ctor;context;constructor(t,e,n,s){this.many=t,this.recursive=e,this.ctor=s,this.context=n||[]}get(t,e){const n=[],s=this.many.length;if(null!=t)for(let e=0;e<s;e++)n.push(this.many[e][t]);else for(let t=0;t<s;t++)n.push(this.many[t]);const r=[n,this.recursive,this.context];return this.recursive&&!e?this.ctor?this.ctor(...r,this.ctor):new i(...r):n}set(t,e){if(void 0===e)return this.set(t,this.get(t,!0));const n=this.many.length,s=e.length;if(null!=t)for(let i=0;i<n;i++)this.many[i][t]=e[Math.min(i,s-1)];else for(let t=0;t<n;t++)this.many[t]=e[Math.min(t,s-1)]}delete(t){for(let e of this.many)delete e[t]}call(t,e){void 0!==t&&t.length||(t=[[]]);const n=[],s=this.many.length,i=t.length;let r,o;if(void 0!==e)for(let h=0;h<s;h++)r=t[Math.min(h,i-1)]||[],o=this.many[h][e](...r,...this.context),n.push(o);else for(let e=0;e<s;e++)r=t[Math.min(e,i-1)]||[],o=this.many[e](...r,...this.context),n.push(o);return n}}export{i as One,t as one,n as unWrap}; | ||
function t(e,n,i,s){const c=new o(e,n,i);return c.ctor=t,void 0!==s&&(c.mainItem=s),new Proxy(c,r)}const e=Symbol();function n(e,n){return e.ctor=t,void 0!==n&&(e.mainItem=n),new Proxy(e,r)}function i(t){return t[e]||t}const r={get(t,n){if(n===e)return t;let i=t.get(n,!0);if(i.length&&"function"==typeof i[0])return void 0!==t.mainItem?(...e)=>t.call([e],n)[t.mainItem]:(...e)=>t.call(e,n);if(t.recursive){if(t.ctor){const n=t.ctor(i,!0,t.context);return(n[e]||n).ctor=t.ctor,n}return new o(i,!0,t.context)}return void 0!==t.mainItem?i[t.mainItem]:i},set:(t,e,n)=>(t.set(e,n),!0)};class o{many;mainItem;recursive;ctor;context;constructor(t,e,n){this.many=t,this.recursive=e,this.context=n||[]}get(t,n){const i=[],r=this.many.length;if(null!=t)for(let e=0;e<r;e++)i.push(this.many[e][t]);else for(let t=0;t<r;t++)i.push(this.many[t]);if(!this.recursive||n)return i;if(!this.ctor)return new o(i,this.recursive,this.context);{const t=this.ctor(i,this.recursive,this.context);(t[e]||t).ctor=this.ctor}}set(t,e){if(void 0===e)return this.set(t,this.get(t,!0));e instanceof Array||(e=[e]);const n=this.many.length,i=e.length;if(null!=t)for(let r=0;r<n;r++)this.many[r][t]=e[Math.min(r,i-1)];else for(let t=0;t<n;t++)this.many[t]=e[Math.min(t,i-1)]}delete(t){for(let e of this.many)delete e[t]}call(t,e){void 0!==t&&t.length||(t=[[]]);const n=[],i=this.many.length,r=t.length;let o,s;if(void 0!==e)for(let c=0;c<i;c++)o=t[Math.min(c,r-1)]||[],s=this.many[c][e](...o,...this.context),n.push(s);else for(let e=0;e<i;e++)o=t[Math.min(e,r-1)]||[],s=this.many[e](...o,...this.context),n.push(s);return n}}export{o as One,t as one,i as unWrap,n as wrap}; |
{ | ||
"name": "deleight", | ||
"version": "1.2.0", | ||
"version": "1.3.0", | ||
"description": "A group of 8 libraries for writing accessible and joyfully interactive web applications with traditional HTML, CSS and JavaScript.", | ||
@@ -5,0 +5,0 @@ "type": "module", |
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
131014
2634