diff --git a/dist/decorators/reactive.d.ts.map b/dist/decorators/reactive.d.ts.map index b3a2d84..66c2914 100644 --- a/dist/decorators/reactive.d.ts.map +++ b/dist/decorators/reactive.d.ts.map @@ -1 +1 @@ -{"version":3,"file":"reactive.d.ts","sourceRoot":"","sources":["../../src/decorators/reactive.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,cAAc,EAAC,MAAM,UAAU,CAAA;AA2C5C,wBAAgB,QAAQ,CAAC,KAAK,EAAE,cAAc,EAAE,OAAO,EAAE,qBAAqB,GAAG,GAAG,CA6CnF"} \ No newline at end of file +{"version":3,"file":"reactive.d.ts","sourceRoot":"","sources":["../../src/decorators/reactive.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,cAAc,EAAC,MAAM,UAAU,CAAA;AA2C5C,wBAAgB,QAAQ,CAAC,KAAK,EAAE,cAAc,EAAE,OAAO,EAAE,qBAAqB,GAAG,GAAG,CAmDnF"} \ No newline at end of file diff --git a/dist/decorators/reactive.js b/dist/decorators/reactive.js index 316f21c..b517567 100644 --- a/dist/decorators/reactive.js +++ b/dist/decorators/reactive.js @@ -70,6 +70,12 @@ export function reactive(value, context) { if (!(hasOwnProperty.call(instance, prop) || hasOwnProperty.call(Class.prototype, prop))) { throw new Error(`Property "${prop.toString()}" not found on instance of class decorated with \`@reactive\`. Did you forget to use the \`@reactive\` decorator on one of your classes that has a "${prop.toString()}" property decorated with \`@signal\`?`); } + + // For now at least, we always override like class fields with + // [[Define]] semantics. Perhaps when @signal is used on a + // getter/setter, we should not override in that case, but patch + // the prototype getter/setter (that'll be a bit of work to + // implement though). const override = true; createSignalAccessor(instance, prop, initialValue, override); } diff --git a/dist/decorators/reactive.js.map b/dist/decorators/reactive.js.map index f9fac2d..94dbc31 100644 --- a/dist/decorators/reactive.js.map +++ b/dist/decorators/reactive.js.map @@ -1 +1 @@ -{"version":3,"file":"reactive.js","names":["getListener","untrack","getKey","getPropsToSignalify","resetPropsToSignalify","getCreateSignalAccessor","accessKey","createSignalAccessor","hasOwnProperty","Object","prototype","reactive","value","context","kind","TypeError","Class","props","ReactiveDecorator","constructor","args","instance","Reflect","construct","new","target","prop","initialValue","call","Error","toString","override"],"sources":["../../src/decorators/reactive.ts"],"sourcesContent":["import type {AnyConstructor} from 'lowclass'\nimport {getListener, untrack} from 'solid-js'\nimport {getKey, getPropsToSignalify, resetPropsToSignalify} from './signal.js'\nimport {getCreateSignalAccessor} from '../signalify.js'\n\n/**\n * Access key for classy-solid private internal APIs.\n */\nconst accessKey = getKey()\n\nconst createSignalAccessor = getCreateSignalAccessor()\nconst hasOwnProperty = Object.prototype.hasOwnProperty\n\n/**\n * A decorator that makes a class reactive, allowing it have properties\n * decorated with `@signal` to make those properties reactive Solid signals.\n *\n * Example:\n *\n * > Note in the following example that `\\@` should be written as `@` without\n * the back slash. The back slash prevents JSDoc parsing errors in this comment\n * in TypeScript. https://github.com/microsoft/TypeScript/issues/47679\n *\n * ```js\n * import {reactive, signal} from 'classy-solid'\n * import {createEffect} from 'solid-js'\n *\n * \\@reactive\n * class Counter {\n * \\@signal count = 0\n *\n * constructor() {\n * setInterval(() => this.count++, 1000)\n * }\n * }\n *\n * const counter = new Counter\n *\n * createEffect(() => {\n * console.log('count:', counter.count)\n * })\n * ```\n */\nexport function reactive(value: AnyConstructor, context: ClassDecoratorContext): any {\n\tif (typeof value !== 'function' || (context && context.kind !== 'class'))\n\t\tthrow new TypeError('The @reactive decorator is only for use on classes.')\n\n\tconst Class = value\n\tconst props = getPropsToSignalify(accessKey)\n\n\t// For the current class decorated with @reactive, we reset the map, so that\n\t// for the next class decorated with @reactive we track only that next\n\t// class's properties that were decorated with @signal. We do this because\n\t// field decorators do not have access to the class or its prototype.\n\t//\n\t// In the future maybe we can use decorator metadata for this\n\t// (https://github.com/tc39/proposal-decorator-metadata)?\n\tresetPropsToSignalify(accessKey)\n\n\tclass ReactiveDecorator extends Class {\n\t\tconstructor(...args: any[]) {\n\t\t\tlet instance!: ReactiveDecorator\n\n\t\t\t// Ensure that if we're in an effect that `new`ing a class does not\n\t\t\t// track signal reads, otherwise we'll get into an infinite loop. If\n\t\t\t// someone want to trigger an effect based on properties of the\n\t\t\t// `new`ed instance, they can explicitly read the properties\n\t\t\t// themselves in the effect, making their intent clear.\n\t\t\tif (getListener()) untrack(() => (instance = Reflect.construct(Class, args, new.target))) // super()\n\t\t\telse super(...args), (instance = this)\n\n\t\t\tfor (const [prop, {initialValue}] of props) {\n\t\t\t\t// @prod-prune\n\t\t\t\tif (!(hasOwnProperty.call(instance, prop) || hasOwnProperty.call(Class.prototype, prop))) {\n\t\t\t\t\tthrow new Error(\n\t\t\t\t\t\t`Property \"${prop.toString()}\" not found on instance of class decorated with \\`@reactive\\`. Did you forget to use the \\`@reactive\\` decorator on one of your classes that has a \"${prop.toString()}\" property decorated with \\`@signal\\`?`,\n\t\t\t\t\t)\n\t\t\t\t}\n\n\t\t\t\tconst override = true\n\t\t\t\tcreateSignalAccessor(instance, prop as Exclude, initialValue, override)\n\t\t\t}\n\n\t\t\treturn instance\n\t\t}\n\t}\n\n\treturn ReactiveDecorator\n}\n"],"mappings":"AACA,SAAQA,WAAW,EAAEC,OAAO,QAAO,UAAU;AAC7C,SAAQC,MAAM,EAAEC,mBAAmB,EAAEC,qBAAqB,QAAO,aAAa;AAC9E,SAAQC,uBAAuB,QAAO,iBAAiB;;AAEvD;AACA;AACA;AACA,MAAMC,SAAS,GAAGJ,MAAM,CAAC,CAAC;AAE1B,MAAMK,oBAAoB,GAAGF,uBAAuB,CAAC,CAAC;AACtD,MAAMG,cAAc,GAAGC,MAAM,CAACC,SAAS,CAACF,cAAc;;AAEtD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,SAASG,QAAQA,CAACC,KAAqB,EAAEC,OAA8B,EAAO;EACpF,IAAI,OAAOD,KAAK,KAAK,UAAU,IAAKC,OAAO,IAAIA,OAAO,CAACC,IAAI,KAAK,OAAQ,EACvE,MAAM,IAAIC,SAAS,CAAC,qDAAqD,CAAC;EAE3E,MAAMC,KAAK,GAAGJ,KAAK;EACnB,MAAMK,KAAK,GAAGd,mBAAmB,CAACG,SAAS,CAAC;;EAE5C;EACA;EACA;EACA;EACA;EACA;EACA;EACAF,qBAAqB,CAACE,SAAS,CAAC;EAEhC,MAAMY,iBAAiB,SAASF,KAAK,CAAC;IACrCG,WAAWA,CAAC,GAAGC,IAAW,EAAE;MAC3B,IAAIC,QAA4B;;MAEhC;MACA;MACA;MACA;MACA;MACA,IAAIrB,WAAW,CAAC,CAAC,EAAEC,OAAO,CAAC,MAAOoB,QAAQ,GAAGC,OAAO,CAACC,SAAS,CAACP,KAAK,EAAEI,IAAI,EAAEI,GAAG,CAACC,MAAM,CAAE,CAAC,EAAC;MAAA,KACrF,KAAK,CAAC,GAAGL,IAAI,CAAC,EAAGC,QAAQ,GAAG,IAAK;MAEtC,KAAK,MAAM,CAACK,IAAI,EAAE;QAACC;MAAY,CAAC,CAAC,IAAIV,KAAK,EAAE;QAC3C;QACA,IAAI,EAAET,cAAc,CAACoB,IAAI,CAACP,QAAQ,EAAEK,IAAI,CAAC,IAAIlB,cAAc,CAACoB,IAAI,CAACZ,KAAK,CAACN,SAAS,EAAEgB,IAAI,CAAC,CAAC,EAAE;UACzF,MAAM,IAAIG,KAAK,CACb,aAAYH,IAAI,CAACI,QAAQ,CAAC,CAAE,uJAAsJJ,IAAI,CAACI,QAAQ,CAAC,CAAE,wCACpM,CAAC;QACF;QAEA,MAAMC,QAAQ,GAAG,IAAI;QACrBxB,oBAAoB,CAACc,QAAQ,EAAEK,IAAI,EAA8CC,YAAY,EAAEI,QAAQ,CAAC;MACzG;MAEA,OAAOV,QAAQ;IAChB;EACD;EAEA,OAAOH,iBAAiB;AACzB"} \ No newline at end of file +{"version":3,"file":"reactive.js","names":["getListener","untrack","getKey","getPropsToSignalify","resetPropsToSignalify","getCreateSignalAccessor","accessKey","createSignalAccessor","hasOwnProperty","Object","prototype","reactive","value","context","kind","TypeError","Class","props","ReactiveDecorator","constructor","args","instance","Reflect","construct","new","target","prop","initialValue","call","Error","toString","override"],"sources":["../../src/decorators/reactive.ts"],"sourcesContent":["import type {AnyConstructor} from 'lowclass'\nimport {getListener, untrack} from 'solid-js'\nimport {getKey, getPropsToSignalify, resetPropsToSignalify} from './signal.js'\nimport {getCreateSignalAccessor} from '../signalify.js'\n\n/**\n * Access key for classy-solid private internal APIs.\n */\nconst accessKey = getKey()\n\nconst createSignalAccessor = getCreateSignalAccessor()\nconst hasOwnProperty = Object.prototype.hasOwnProperty\n\n/**\n * A decorator that makes a class reactive, allowing it have properties\n * decorated with `@signal` to make those properties reactive Solid signals.\n *\n * Example:\n *\n * > Note in the following example that `\\@` should be written as `@` without\n * the back slash. The back slash prevents JSDoc parsing errors in this comment\n * in TypeScript. https://github.com/microsoft/TypeScript/issues/47679\n *\n * ```js\n * import {reactive, signal} from 'classy-solid'\n * import {createEffect} from 'solid-js'\n *\n * \\@reactive\n * class Counter {\n * \\@signal count = 0\n *\n * constructor() {\n * setInterval(() => this.count++, 1000)\n * }\n * }\n *\n * const counter = new Counter\n *\n * createEffect(() => {\n * console.log('count:', counter.count)\n * })\n * ```\n */\nexport function reactive(value: AnyConstructor, context: ClassDecoratorContext): any {\n\tif (typeof value !== 'function' || (context && context.kind !== 'class'))\n\t\tthrow new TypeError('The @reactive decorator is only for use on classes.')\n\n\tconst Class = value\n\tconst props = getPropsToSignalify(accessKey)\n\n\t// For the current class decorated with @reactive, we reset the map, so that\n\t// for the next class decorated with @reactive we track only that next\n\t// class's properties that were decorated with @signal. We do this because\n\t// field decorators do not have access to the class or its prototype.\n\t//\n\t// In the future maybe we can use decorator metadata for this\n\t// (https://github.com/tc39/proposal-decorator-metadata)?\n\tresetPropsToSignalify(accessKey)\n\n\tclass ReactiveDecorator extends Class {\n\t\tconstructor(...args: any[]) {\n\t\t\tlet instance!: ReactiveDecorator\n\n\t\t\t// Ensure that if we're in an effect that `new`ing a class does not\n\t\t\t// track signal reads, otherwise we'll get into an infinite loop. If\n\t\t\t// someone want to trigger an effect based on properties of the\n\t\t\t// `new`ed instance, they can explicitly read the properties\n\t\t\t// themselves in the effect, making their intent clear.\n\t\t\tif (getListener()) untrack(() => (instance = Reflect.construct(Class, args, new.target))) // super()\n\t\t\telse super(...args), (instance = this)\n\n\t\t\tfor (const [prop, {initialValue}] of props) {\n\t\t\t\t// @prod-prune\n\t\t\t\tif (!(hasOwnProperty.call(instance, prop) || hasOwnProperty.call(Class.prototype, prop))) {\n\t\t\t\t\tthrow new Error(\n\t\t\t\t\t\t`Property \"${prop.toString()}\" not found on instance of class decorated with \\`@reactive\\`. Did you forget to use the \\`@reactive\\` decorator on one of your classes that has a \"${prop.toString()}\" property decorated with \\`@signal\\`?`,\n\t\t\t\t\t)\n\t\t\t\t}\n\n\t\t\t\t// For now at least, we always override like class fields with\n\t\t\t\t// [[Define]] semantics. Perhaps when @signal is used on a\n\t\t\t\t// getter/setter, we should not override in that case, but patch\n\t\t\t\t// the prototype getter/setter (that'll be a bit of work to\n\t\t\t\t// implement though).\n\t\t\t\tconst override = true\n\n\t\t\t\tcreateSignalAccessor(instance, prop as Exclude, initialValue, override)\n\t\t\t}\n\n\t\t\treturn instance\n\t\t}\n\t}\n\n\treturn ReactiveDecorator\n}\n"],"mappings":"AACA,SAAQA,WAAW,EAAEC,OAAO,QAAO,UAAU;AAC7C,SAAQC,MAAM,EAAEC,mBAAmB,EAAEC,qBAAqB,QAAO,aAAa;AAC9E,SAAQC,uBAAuB,QAAO,iBAAiB;;AAEvD;AACA;AACA;AACA,MAAMC,SAAS,GAAGJ,MAAM,CAAC,CAAC;AAE1B,MAAMK,oBAAoB,GAAGF,uBAAuB,CAAC,CAAC;AACtD,MAAMG,cAAc,GAAGC,MAAM,CAACC,SAAS,CAACF,cAAc;;AAEtD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,SAASG,QAAQA,CAACC,KAAqB,EAAEC,OAA8B,EAAO;EACpF,IAAI,OAAOD,KAAK,KAAK,UAAU,IAAKC,OAAO,IAAIA,OAAO,CAACC,IAAI,KAAK,OAAQ,EACvE,MAAM,IAAIC,SAAS,CAAC,qDAAqD,CAAC;EAE3E,MAAMC,KAAK,GAAGJ,KAAK;EACnB,MAAMK,KAAK,GAAGd,mBAAmB,CAACG,SAAS,CAAC;;EAE5C;EACA;EACA;EACA;EACA;EACA;EACA;EACAF,qBAAqB,CAACE,SAAS,CAAC;EAEhC,MAAMY,iBAAiB,SAASF,KAAK,CAAC;IACrCG,WAAWA,CAAC,GAAGC,IAAW,EAAE;MAC3B,IAAIC,QAA4B;;MAEhC;MACA;MACA;MACA;MACA;MACA,IAAIrB,WAAW,CAAC,CAAC,EAAEC,OAAO,CAAC,MAAOoB,QAAQ,GAAGC,OAAO,CAACC,SAAS,CAACP,KAAK,EAAEI,IAAI,EAAEI,GAAG,CAACC,MAAM,CAAE,CAAC,EAAC;MAAA,KACrF,KAAK,CAAC,GAAGL,IAAI,CAAC,EAAGC,QAAQ,GAAG,IAAK;MAEtC,KAAK,MAAM,CAACK,IAAI,EAAE;QAACC;MAAY,CAAC,CAAC,IAAIV,KAAK,EAAE;QAC3C;QACA,IAAI,EAAET,cAAc,CAACoB,IAAI,CAACP,QAAQ,EAAEK,IAAI,CAAC,IAAIlB,cAAc,CAACoB,IAAI,CAACZ,KAAK,CAACN,SAAS,EAAEgB,IAAI,CAAC,CAAC,EAAE;UACzF,MAAM,IAAIG,KAAK,CACb,aAAYH,IAAI,CAACI,QAAQ,CAAC,CAAE,uJAAsJJ,IAAI,CAACI,QAAQ,CAAC,CAAE,wCACpM,CAAC;QACF;;QAEA;QACA;QACA;QACA;QACA;QACA,MAAMC,QAAQ,GAAG,IAAI;QAErBxB,oBAAoB,CAACc,QAAQ,EAAEK,IAAI,EAA8CC,YAAY,EAAEI,QAAQ,CAAC;MACzG;MAEA,OAAOV,QAAQ;IAChB;EACD;EAEA,OAAOH,iBAAiB;AACzB"} \ No newline at end of file diff --git a/dist/signalify.d.ts.map b/dist/signalify.d.ts.map index e9550eb..cdae35b 100644 --- a/dist/signalify.d.ts.map +++ b/dist/signalify.d.ts.map @@ -1 +1 @@ -{"version":3,"file":"signalify.d.ts","sourceRoot":"","sources":["../src/signalify.ts"],"names":[],"mappings":"AAwDA,wBAAgB,SAAS,CAAC,CAAC,SAAS,MAAM,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,KAAK,EAAE,CAAC,MAAM,CAAC,CAAC,EAAE,GAAG,CAAC,CAAA;AAC7E,wBAAgB,SAAS,CAAC,CAAC,SAAS,MAAM,EAAE,CAAC,SAAS,MAAM,CAAC,EAAE,GAAG,EAAE,CAAC,GAAG,CAAC,CAAA;AAiBzE,wBAAgB,uBAAuB,gCAItC;AASD,wBAAgB,sBAAsB,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,WAE7E;AASD,iBAAS,oBAAoB,CAAC,CAAC,SAAS,MAAM,EAC7C,GAAG,EAAE,CAAC,EACN,IAAI,EAAE,OAAO,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC,EAC9B,UAAU,GAAE,OAAmB,EAC/B,QAAQ,UAAQ,GACd,IAAI,CA8FN"} \ No newline at end of file +{"version":3,"file":"signalify.d.ts","sourceRoot":"","sources":["../src/signalify.ts"],"names":[],"mappings":"AAwDA,wBAAgB,SAAS,CAAC,CAAC,SAAS,MAAM,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,KAAK,EAAE,CAAC,MAAM,CAAC,CAAC,EAAE,GAAG,CAAC,CAAA;AAC7E,wBAAgB,SAAS,CAAC,CAAC,SAAS,MAAM,EAAE,CAAC,SAAS,MAAM,CAAC,EAAE,GAAG,EAAE,CAAC,GAAG,CAAC,CAAA;AAiBzE,wBAAgB,uBAAuB,gCAItC;AASD,wBAAgB,sBAAsB,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,WAE7E;AASD,iBAAS,oBAAoB,CAAC,CAAC,SAAS,MAAM,EAC7C,GAAG,EAAE,CAAC,EACN,IAAI,EAAE,OAAO,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC,EAC9B,UAAU,GAAE,OAAmB,EAe/B,QAAQ,UAAQ,GACd,IAAI,CAgGN"} \ No newline at end of file diff --git a/dist/signalify.js b/dist/signalify.js index 6640d46..91b0b94 100644 --- a/dist/signalify.js +++ b/dist/signalify.js @@ -84,7 +84,22 @@ function trackPropSetAtLeastOnce(instance, prop) { propsSetAtLeastOnce.get(instance).add(prop); } const isSignalGetter = new WeakSet(); -function createSignalAccessor(obj, prop, initialVal = obj[prop], override = false) { +function createSignalAccessor(obj, prop, initialVal = obj[prop], +// If an object already has a particular signalified property, override it +// with a new one anyway (useful for maintaining consistency with class +// inheritance where class fields always override fields from base classes +// due to their [[Define]] semantics). False is a good default for signalify() +// usage where someone is augmenting an existing object, but true is more +// useful with usage of @signal on class fields. +// +// Note that if @signal were to specify this as false, it would cause +// @signal-decorated subclass fields to override base class +// @signal-decorated fields with a new value descriptor but without +// signalifiying the field, effectively disabling reactivity, which is a bug +// (a field decorated with @signal *must* be reactive). The test named +// "maintains reactivity in subclass overridden fields" was added to ensure +// that the subclass use case works. +override = false) { if (!override && signalifiedProps.get(obj)?.has(prop)) return; // Special case for Solid proxies: if the object is already a solid proxy, @@ -99,7 +114,9 @@ function createSignalAccessor(obj, prop, initialVal = obj[prop], override = fals originalGet = descriptor.get; originalSet = descriptor.set; - // If we have a signal accessor, no need to create another signal accessor. + // Even if override is true, if we have a signal accessor, there's no + // need to replace it with another signal accessor. We only need to + // override when the current descriptor is not a signal accessor. if (originalGet && isSignalGetter.has(originalGet)) return; if (originalGet || originalSet) { // reactivity requires both diff --git a/dist/signalify.js.map b/dist/signalify.js.map index 5cf2a31..ec9f57f 100644 --- a/dist/signalify.js.map +++ b/dist/signalify.js.map @@ -1 +1 @@ -{"version":3,"file":"signalify.js","names":["getInheritedDescriptor","createSignal","$PROXY","signalifiedProps","WeakMap","signalify","obj","props","_props","length","Object","keys","concat","getOwnPropertySymbols","prop","createSignalAccessor","gotCreateSignalAccessor","getCreateSignalAccessor","Error","propsSetAtLeastOnce","__isPropSetAtLeastOnce","instance","get","has","trackPropSetAtLeastOnce","set","Set","add","isSignalGetter","WeakSet","initialVal","override","proxy","descriptor","originalGet","originalSet","console","warn","toString","value","writable","configurable","enumerable","s","getSignal","call","newValue","v","defineProperty","signals","signalKey","initialValue","undefined","Map","equals"],"sources":["../src/signalify.ts"],"sourcesContent":["import {getInheritedDescriptor} from 'lowclass'\nimport {createSignal, $PROXY} from 'solid-js'\nimport type {Signal} from 'solid-js/types/reactive/signal'\nimport type {PropKey, PropSpec} from './decorators/types.js'\n\nconst signalifiedProps = new WeakMap>()\n\n/**\n * Convert properties on an object into Solid signal-backed properties.\n *\n * There are two ways to use this: either by defining which properties to\n * convert to signal-backed properties by providing an array as property names\n * in the second arg, which is useful on plain objects, or by passing in `this`\n * and `this.constructor` within the `constructor` of a class that has\n * properties decorated with `@signal`.\n *\n * Example with a class:\n *\n * ```js\n * import {signalify} from 'classy-solid'\n * import {createEffect} from 'solid-js'\n *\n * class Counter {\n * count = 0\n *\n * constructor() {\n * signalify(this, 'count')\n * setInterval(() => this.count++, 1000)\n * }\n * }\n *\n * const counter = new Counter\n *\n * createEffect(() => {\n * console.log('count:', counter.count)\n * })\n * ```\n *\n * Example with a plain object:\n *\n * ```js\n * import {signalify} from 'classy-solid'\n * import {createEffect} from 'solid-js'\n *\n * const counter = {\n * count: 0\n * }\n *\n * signalify(counter, 'count')\n * setInterval(() => counter.count++, 1000)\n *\n * createEffect(() => {\n * console.log('count:', counter.count)\n * })\n * ```\n */\nexport function signalify(obj: T, ...props: (keyof T)[]): T\nexport function signalify(obj: T): T\nexport function signalify(obj: Obj, ...props: [] | [Map] | PropertyKey[]) {\n\t// We cast from PropertyKey[] to PropKey[] because numbers can't actually be keys, only string | symbol.\n\tconst _props = props.length\n\t\t? (props as PropKey[])\n\t\t: (Object.keys(obj) as PropKey[]).concat(Object.getOwnPropertySymbols(obj))\n\n\tfor (const prop of _props) createSignalAccessor(obj, prop)\n\n\treturn obj\n}\n\nlet gotCreateSignalAccessor = false\n\n/**\n * This ensures that `createSignalAccessor` is kept internal to classy-solid only.\n */\nexport function getCreateSignalAccessor() {\n\tif (gotCreateSignalAccessor) throw new Error('Export \"createSignalAccessor\" is internal to classy-solid only.')\n\tgotCreateSignalAccessor = true\n\treturn createSignalAccessor\n}\n\n// propsSetAtLeastOnce is a Set that tracks which reactive properties have been\n// set at least once.\nconst propsSetAtLeastOnce = new WeakMap>()\n\n// @lume/element uses this to detect if a reactive prop has been set, and if so\n// will not overwrite the value with any pre-existing value from custom element\n// pre-upgrade.\nexport function __isPropSetAtLeastOnce(instance: object, prop: string | symbol) {\n\treturn !!propsSetAtLeastOnce.get(instance)?.has(prop)\n}\n\nfunction trackPropSetAtLeastOnce(instance: object, prop: string | symbol) {\n\tif (!propsSetAtLeastOnce.has(instance)) propsSetAtLeastOnce.set(instance, new Set())\n\tpropsSetAtLeastOnce.get(instance)!.add(prop)\n}\n\nconst isSignalGetter = new WeakSet()\n\nfunction createSignalAccessor(\n\tobj: T,\n\tprop: Exclude,\n\tinitialVal: unknown = obj[prop],\n\toverride = false,\n): void {\n\tif (!override && signalifiedProps.get(obj)?.has(prop)) return\n\n\t// Special case for Solid proxies: if the object is already a solid proxy,\n\t// all properties are already reactive, no need to signalify.\n\t// @ts-expect-error special indexed access\n\tconst proxy = obj[$PROXY] as T\n\tif (proxy) return\n\n\tlet descriptor: PropertyDescriptor | undefined = getInheritedDescriptor(obj, prop)\n\n\tlet originalGet: (() => any) | undefined\n\tlet originalSet: ((v: any) => void) | undefined\n\n\tif (descriptor) {\n\t\toriginalGet = descriptor.get\n\t\toriginalSet = descriptor.set\n\n\t\t// If we have a signal accessor, no need to create another signal accessor.\n\t\tif (originalGet && isSignalGetter.has(originalGet)) return\n\n\t\tif (originalGet || originalSet) {\n\t\t\t// reactivity requires both\n\t\t\tif (!originalGet || !originalSet) {\n\t\t\t\tconsole.warn(\n\t\t\t\t\t`The \\`@signal\\` decorator was used on an accessor named \"${prop.toString()}\" which had a getter or a setter, but not both. Reactivity on accessors works only when accessors have both get and set. In this case the decorator does not do anything.`,\n\t\t\t\t)\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\tdelete descriptor.get\n\t\t\tdelete descriptor.set\n\t\t} else {\n\t\t\t// If there was a value descriptor, trust it as the source of truth\n\t\t\t// for initialVal. For example, if the user class modifies the value\n\t\t\t// after the initializer, it will have a different value than what\n\t\t\t// we tracked from the initializer.\n\t\t\tinitialVal = descriptor.value\n\n\t\t\t// if it isn't writable, we don't need to make a reactive variable because\n\t\t\t// the value won't change\n\t\t\tif (!descriptor.writable) {\n\t\t\t\tconsole.warn(\n\t\t\t\t\t`The \\`@signal\\` decorator was used on a property named \"${prop.toString()}\" that is not writable. Reactivity is not enabled for non-writable properties.`,\n\t\t\t\t)\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\tdelete descriptor.value\n\t\t\tdelete descriptor.writable\n\t\t}\n\t}\n\n\tdescriptor = {\n\t\tconfigurable: true,\n\t\tenumerable: true,\n\t\t...descriptor,\n\t\tget: originalGet\n\t\t\t? function (this: T): unknown {\n\t\t\t\t\tconst s = getSignal(this, prop, initialVal)\n\t\t\t\t\ts[0]() // read\n\t\t\t\t\treturn originalGet!.call(this)\n\t\t\t }\n\t\t\t: function (this: any): unknown {\n\t\t\t\t\tconst s = getSignal(this, prop, initialVal)\n\t\t\t\t\treturn s[0]() // read\n\t\t\t },\n\t\tset: originalSet\n\t\t\t? function (this: any, newValue: unknown) {\n\t\t\t\t\toriginalSet!.call(this, newValue)\n\n\t\t\t\t\ttrackPropSetAtLeastOnce(this, prop)\n\n\t\t\t\t\tconst v = getSignal(this, prop)\n\t\t\t\t\t// write\n\t\t\t\t\tif (typeof newValue === 'function') v[1](() => newValue)\n\t\t\t\t\telse v[1](newValue)\n\t\t\t }\n\t\t\t: function (this: any, newValue: unknown) {\n\t\t\t\t\ttrackPropSetAtLeastOnce(this, prop)\n\n\t\t\t\t\tconst v = getSignal(this, prop)\n\t\t\t\t\t// write\n\t\t\t\t\tif (typeof newValue === 'function') v[1](() => newValue)\n\t\t\t\t\telse v[1](newValue)\n\t\t\t },\n\t}\n\n\tisSignalGetter.add(descriptor.get!)\n\n\tObject.defineProperty(obj, prop, descriptor)\n\n\tif (!signalifiedProps.has(obj)) signalifiedProps.set(obj, new Set())\n\tsignalifiedProps.get(obj)!.add(prop)\n}\n\nconst signals = new WeakMap>>()\n\nfunction getSignal(instance: object, signalKey: PropKey, initialValue: T = undefined!): Signal {\n\tif (!signals.has(instance)) signals.set(instance, new Map())\n\n\tlet s = signals.get(instance)!.get(signalKey) as Signal | undefined\n\n\tif (s) return s\n\n\ts = createSignal(initialValue, {equals: false})\n\tsignals.get(instance)?.set(signalKey, s as Signal)\n\n\treturn s\n}\n\ntype Obj = Record\n"],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"signalify.js","names":["getInheritedDescriptor","createSignal","$PROXY","signalifiedProps","WeakMap","signalify","obj","props","_props","length","Object","keys","concat","getOwnPropertySymbols","prop","createSignalAccessor","gotCreateSignalAccessor","getCreateSignalAccessor","Error","propsSetAtLeastOnce","__isPropSetAtLeastOnce","instance","get","has","trackPropSetAtLeastOnce","set","Set","add","isSignalGetter","WeakSet","initialVal","override","proxy","descriptor","originalGet","originalSet","console","warn","toString","value","writable","configurable","enumerable","s","getSignal","call","newValue","v","defineProperty","signals","signalKey","initialValue","undefined","Map","equals"],"sources":["../src/signalify.ts"],"sourcesContent":["import {getInheritedDescriptor} from 'lowclass'\nimport {createSignal, $PROXY} from 'solid-js'\nimport type {Signal} from 'solid-js/types/reactive/signal'\nimport type {PropKey, PropSpec} from './decorators/types.js'\n\nconst signalifiedProps = new WeakMap>()\n\n/**\n * Convert properties on an object into Solid signal-backed properties.\n *\n * There are two ways to use this: either by defining which properties to\n * convert to signal-backed properties by providing an array as property names\n * in the second arg, which is useful on plain objects, or by passing in `this`\n * and `this.constructor` within the `constructor` of a class that has\n * properties decorated with `@signal`.\n *\n * Example with a class:\n *\n * ```js\n * import {signalify} from 'classy-solid'\n * import {createEffect} from 'solid-js'\n *\n * class Counter {\n * count = 0\n *\n * constructor() {\n * signalify(this, 'count')\n * setInterval(() => this.count++, 1000)\n * }\n * }\n *\n * const counter = new Counter\n *\n * createEffect(() => {\n * console.log('count:', counter.count)\n * })\n * ```\n *\n * Example with a plain object:\n *\n * ```js\n * import {signalify} from 'classy-solid'\n * import {createEffect} from 'solid-js'\n *\n * const counter = {\n * count: 0\n * }\n *\n * signalify(counter, 'count')\n * setInterval(() => counter.count++, 1000)\n *\n * createEffect(() => {\n * console.log('count:', counter.count)\n * })\n * ```\n */\nexport function signalify(obj: T, ...props: (keyof T)[]): T\nexport function signalify(obj: T): T\nexport function signalify(obj: Obj, ...props: [] | [Map] | PropertyKey[]) {\n\t// We cast from PropertyKey[] to PropKey[] because numbers can't actually be keys, only string | symbol.\n\tconst _props = props.length\n\t\t? (props as PropKey[])\n\t\t: (Object.keys(obj) as PropKey[]).concat(Object.getOwnPropertySymbols(obj))\n\n\tfor (const prop of _props) createSignalAccessor(obj, prop)\n\n\treturn obj\n}\n\nlet gotCreateSignalAccessor = false\n\n/**\n * This ensures that `createSignalAccessor` is kept internal to classy-solid only.\n */\nexport function getCreateSignalAccessor() {\n\tif (gotCreateSignalAccessor) throw new Error('Export \"createSignalAccessor\" is internal to classy-solid only.')\n\tgotCreateSignalAccessor = true\n\treturn createSignalAccessor\n}\n\n// propsSetAtLeastOnce is a Set that tracks which reactive properties have been\n// set at least once.\nconst propsSetAtLeastOnce = new WeakMap>()\n\n// @lume/element uses this to detect if a reactive prop has been set, and if so\n// will not overwrite the value with any pre-existing value from custom element\n// pre-upgrade.\nexport function __isPropSetAtLeastOnce(instance: object, prop: string | symbol) {\n\treturn !!propsSetAtLeastOnce.get(instance)?.has(prop)\n}\n\nfunction trackPropSetAtLeastOnce(instance: object, prop: string | symbol) {\n\tif (!propsSetAtLeastOnce.has(instance)) propsSetAtLeastOnce.set(instance, new Set())\n\tpropsSetAtLeastOnce.get(instance)!.add(prop)\n}\n\nconst isSignalGetter = new WeakSet()\n\nfunction createSignalAccessor(\n\tobj: T,\n\tprop: Exclude,\n\tinitialVal: unknown = obj[prop],\n\t// If an object already has a particular signalified property, override it\n\t// with a new one anyway (useful for maintaining consistency with class\n\t// inheritance where class fields always override fields from base classes\n\t// due to their [[Define]] semantics). False is a good default for signalify()\n\t// usage where someone is augmenting an existing object, but true is more\n\t// useful with usage of @signal on class fields.\n\t//\n\t// Note that if @signal were to specify this as false, it would cause\n\t// @signal-decorated subclass fields to override base class\n\t// @signal-decorated fields with a new value descriptor but without\n\t// signalifiying the field, effectively disabling reactivity, which is a bug\n\t// (a field decorated with @signal *must* be reactive). The test named\n\t// \"maintains reactivity in subclass overridden fields\" was added to ensure\n\t// that the subclass use case works.\n\toverride = false,\n): void {\n\tif (!override && signalifiedProps.get(obj)?.has(prop)) return\n\n\t// Special case for Solid proxies: if the object is already a solid proxy,\n\t// all properties are already reactive, no need to signalify.\n\t// @ts-expect-error special indexed access\n\tconst proxy = obj[$PROXY] as T\n\tif (proxy) return\n\n\tlet descriptor: PropertyDescriptor | undefined = getInheritedDescriptor(obj, prop)\n\n\tlet originalGet: (() => any) | undefined\n\tlet originalSet: ((v: any) => void) | undefined\n\n\tif (descriptor) {\n\t\toriginalGet = descriptor.get\n\t\toriginalSet = descriptor.set\n\n\t\t// Even if override is true, if we have a signal accessor, there's no\n\t\t// need to replace it with another signal accessor. We only need to\n\t\t// override when the current descriptor is not a signal accessor.\n\t\tif (originalGet && isSignalGetter.has(originalGet)) return\n\n\t\tif (originalGet || originalSet) {\n\t\t\t// reactivity requires both\n\t\t\tif (!originalGet || !originalSet) {\n\t\t\t\tconsole.warn(\n\t\t\t\t\t`The \\`@signal\\` decorator was used on an accessor named \"${prop.toString()}\" which had a getter or a setter, but not both. Reactivity on accessors works only when accessors have both get and set. In this case the decorator does not do anything.`,\n\t\t\t\t)\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\tdelete descriptor.get\n\t\t\tdelete descriptor.set\n\t\t} else {\n\t\t\t// If there was a value descriptor, trust it as the source of truth\n\t\t\t// for initialVal. For example, if the user class modifies the value\n\t\t\t// after the initializer, it will have a different value than what\n\t\t\t// we tracked from the initializer.\n\t\t\tinitialVal = descriptor.value\n\n\t\t\t// if it isn't writable, we don't need to make a reactive variable because\n\t\t\t// the value won't change\n\t\t\tif (!descriptor.writable) {\n\t\t\t\tconsole.warn(\n\t\t\t\t\t`The \\`@signal\\` decorator was used on a property named \"${prop.toString()}\" that is not writable. Reactivity is not enabled for non-writable properties.`,\n\t\t\t\t)\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\tdelete descriptor.value\n\t\t\tdelete descriptor.writable\n\t\t}\n\t}\n\n\tdescriptor = {\n\t\tconfigurable: true,\n\t\tenumerable: true,\n\t\t...descriptor,\n\t\tget: originalGet\n\t\t\t? function (this: T): unknown {\n\t\t\t\t\tconst s = getSignal(this, prop, initialVal)\n\t\t\t\t\ts[0]() // read\n\t\t\t\t\treturn originalGet!.call(this)\n\t\t\t }\n\t\t\t: function (this: any): unknown {\n\t\t\t\t\tconst s = getSignal(this, prop, initialVal)\n\t\t\t\t\treturn s[0]() // read\n\t\t\t },\n\t\tset: originalSet\n\t\t\t? function (this: any, newValue: unknown) {\n\t\t\t\t\toriginalSet!.call(this, newValue)\n\n\t\t\t\t\ttrackPropSetAtLeastOnce(this, prop)\n\n\t\t\t\t\tconst v = getSignal(this, prop)\n\t\t\t\t\t// write\n\t\t\t\t\tif (typeof newValue === 'function') v[1](() => newValue)\n\t\t\t\t\telse v[1](newValue)\n\t\t\t }\n\t\t\t: function (this: any, newValue: unknown) {\n\t\t\t\t\ttrackPropSetAtLeastOnce(this, prop)\n\n\t\t\t\t\tconst v = getSignal(this, prop)\n\t\t\t\t\t// write\n\t\t\t\t\tif (typeof newValue === 'function') v[1](() => newValue)\n\t\t\t\t\telse v[1](newValue)\n\t\t\t },\n\t}\n\n\tisSignalGetter.add(descriptor.get!)\n\n\tObject.defineProperty(obj, prop, descriptor)\n\n\tif (!signalifiedProps.has(obj)) signalifiedProps.set(obj, new Set())\n\tsignalifiedProps.get(obj)!.add(prop)\n}\n\nconst signals = new WeakMap>>()\n\nfunction getSignal(instance: object, signalKey: PropKey, initialValue: T = undefined!): Signal {\n\tif (!signals.has(instance)) signals.set(instance, new Map())\n\n\tlet s = signals.get(instance)!.get(signalKey) as Signal | undefined\n\n\tif (s) return s\n\n\ts = createSignal(initialValue, {equals: false})\n\tsignals.get(instance)?.set(signalKey, s as Signal)\n\n\treturn s\n}\n\ntype Obj = Record\n"],"mappings":"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"} \ No newline at end of file diff --git a/package.json b/package.json index d71c94d..cc25b3f 100644 --- a/package.json +++ b/package.json @@ -37,7 +37,7 @@ "example": "five-server . --open=example" }, "dependencies": { - "lowclass": "^6.0.0", + "lowclass": "^7.0.0", "solid-js": "^1.3.13" }, "devDependencies": {