@solid-primitives/destructure
Advanced tools
+9
-11
@@ -1,6 +0,5 @@ | ||
| import { MemoOptions, Accessor } from 'solid-js'; | ||
| import { Values, AnyFunction, MaybeAccessor, AnyObject } from '@solid-primitives/utils'; | ||
| import { Accessor, MemoOptions } from "solid-js"; | ||
| import { MaybeAccessor, AnyObject, Values, AnyFunction } from "@solid-primitives/utils"; | ||
| type ReactiveSource = [] | any[] | AnyObject; | ||
| type DestructureOptions<T extends ReactiveSource> = MemoOptions<Values<T>> & { | ||
| export type DestructureOptions<T extends ReactiveSource> = MemoOptions<Values<T>> & { | ||
| memo?: boolean; | ||
@@ -10,12 +9,12 @@ lazy?: boolean; | ||
| }; | ||
| type Spread<T extends ReactiveSource> = { | ||
| export type Spread<T extends ReactiveSource> = { | ||
| readonly [K in keyof T]: Accessor<T[K]>; | ||
| }; | ||
| type DeepSpread<T extends ReactiveSource> = { | ||
| export type DeepSpread<T extends ReactiveSource> = { | ||
| readonly [K in keyof T]: T[K] extends ReactiveSource ? T[K] extends AnyFunction ? Accessor<T[K]> : DeepSpread<T[K]> : Accessor<T[K]>; | ||
| }; | ||
| type Destructure<T extends ReactiveSource> = { | ||
| export type Destructure<T extends ReactiveSource> = { | ||
| readonly [K in keyof T]-?: Accessor<T[K]>; | ||
| }; | ||
| type DeepDestructure<T extends ReactiveSource> = { | ||
| export type DeepDestructure<T extends ReactiveSource> = { | ||
| readonly [K in keyof T]-?: T[K] extends ReactiveSource ? T[K] extends AnyFunction ? Accessor<T[K]> : DeepDestructure<T[K]> : Accessor<T[K]>; | ||
@@ -41,7 +40,6 @@ }; | ||
| */ | ||
| declare function destructure<T extends ReactiveSource, O extends DestructureOptions<T>>(source: MaybeAccessor<T>, options?: O): O extends { | ||
| export declare function destructure<T extends ReactiveSource, O extends DestructureOptions<T>>(source: MaybeAccessor<T>, options?: O): O extends { | ||
| lazy: true; | ||
| deep: true; | ||
| } ? DeepDestructure<T> : O["lazy"] extends true ? Destructure<T> : O["deep"] extends true ? DeepSpread<T> : Spread<T>; | ||
| export { DeepDestructure, DeepSpread, Destructure, DestructureOptions, Spread, destructure }; | ||
| export {}; |
+65
-46
@@ -1,49 +0,68 @@ | ||
| import { getOwner, createMemo, runWithOwner } from 'solid-js'; | ||
| import { access } from '@solid-primitives/utils'; | ||
| // src/index.ts | ||
| var isReactiveObject = (value) => typeof value === "object" && value !== null; | ||
| import { createMemo, runWithOwner, getOwner } from "solid-js"; | ||
| import { access } from "@solid-primitives/utils"; | ||
| const isReactiveObject = (value) => typeof value === "object" && value !== null; | ||
| /** | ||
| * Cashed object getters. | ||
| * @description When a key is accessed for the first time, the `get` function is executed, later a cached value is used instead. | ||
| */ | ||
| function createProxyCache(obj, get) { | ||
| return new Proxy( | ||
| {}, | ||
| { | ||
| get: (target, key) => { | ||
| if (key === Symbol.iterator || key === "length") | ||
| return Reflect.get(obj, key); | ||
| const saved = Reflect.get(target, key); | ||
| if (saved) | ||
| return saved; | ||
| const value = get(key); | ||
| Reflect.set(target, key, value); | ||
| return value; | ||
| }, | ||
| set: () => false | ||
| return new Proxy({}, { | ||
| get: (target, key) => { | ||
| if (key === Symbol.iterator || key === "length") | ||
| return Reflect.get(obj, key); | ||
| const saved = Reflect.get(target, key); | ||
| if (saved) | ||
| return saved; | ||
| const value = get(key); | ||
| Reflect.set(target, key, value); | ||
| return value; | ||
| }, | ||
| set: () => false, | ||
| }); | ||
| } | ||
| /** | ||
| * Destructures an reactive object *(e.g. store or component props)* or a signal of one into a tuple/map of signals for each object key. | ||
| * @param source reactive object or signal returning one | ||
| * @param options memo options + primitive configuration: | ||
| * - `memo` - wraps accessors in `createMemo`, making each property update independently. *(enabled by default for signal source)* | ||
| * - `lazy` - property accessors are created on key read. enable if you want to only a subset of source properties, or use properties initially missing | ||
| * - `deep` - destructure nested objects | ||
| * @returns object of the same keys as the source, but with values turned into accessors. | ||
| * @example // spread tuples | ||
| * const [first, second, third] = destructure(() => [1,2,3]) | ||
| * first() // => 1 | ||
| * second() // => 2 | ||
| * third() // => 3 | ||
| * @example // spread objects | ||
| * const { name, age } = destructure({ name: "John", age: 36 }) | ||
| * name() // => "John" | ||
| * age() // => 36 | ||
| */ | ||
| export function destructure(source, options) { | ||
| const config = options ?? {}; | ||
| const memo = config.memo ?? typeof source === "function"; | ||
| const getter = typeof source === "function" | ||
| ? (key) => () => source()[key] | ||
| : (key) => () => source[key]; | ||
| const obj = access(source); | ||
| // lazy (use proxy) | ||
| if (config.lazy) { | ||
| const owner = getOwner(); | ||
| return createProxyCache(obj, key => { | ||
| const calc = getter(key); | ||
| if (config.deep && isReactiveObject(obj[key])) | ||
| return runWithOwner(owner, () => destructure(calc, { ...config, memo })); | ||
| return memo ? runWithOwner(owner, () => createMemo(calc, undefined, options)) : calc; | ||
| }); | ||
| } | ||
| ); | ||
| // eager (loop keys) | ||
| const result = Array.isArray(obj) ? [] : {}; | ||
| for (const [key, value] of Object.entries(obj)) { | ||
| const calc = getter(key); | ||
| if (config.deep && isReactiveObject(value)) | ||
| result[key] = destructure(calc, { ...config, memo }); | ||
| else | ||
| result[key] = memo ? createMemo(calc, undefined, options) : calc; | ||
| } | ||
| return result; | ||
| } | ||
| function destructure(source, options) { | ||
| const config = options ?? {}; | ||
| const memo = config.memo ?? typeof source === "function"; | ||
| const getter = typeof source === "function" ? (key) => () => source()[key] : (key) => () => source[key]; | ||
| const obj = access(source); | ||
| if (config.lazy) { | ||
| const owner = getOwner(); | ||
| return createProxyCache(obj, (key) => { | ||
| const calc = getter(key); | ||
| if (config.deep && isReactiveObject(obj[key])) | ||
| return runWithOwner(owner, () => destructure(calc, { ...config, memo })); | ||
| return memo ? runWithOwner(owner, () => createMemo(calc, void 0, options)) : calc; | ||
| }); | ||
| } | ||
| const result = Array.isArray(obj) ? [] : {}; | ||
| for (const [key, value] of Object.entries(obj)) { | ||
| const calc = getter(key); | ||
| if (config.deep && isReactiveObject(value)) | ||
| result[key] = destructure(calc, { ...config, memo }); | ||
| else | ||
| result[key] = memo ? createMemo(calc, void 0, options) : calc; | ||
| } | ||
| return result; | ||
| } | ||
| export { destructure }; |
+3
-7
| { | ||
| "name": "@solid-primitives/destructure", | ||
| "version": "0.1.17", | ||
| "version": "0.2.0", | ||
| "description": "Primitives for destructuring reactive objects – like props or stores – or signals of them into a separate accessors updated individually.", | ||
@@ -29,3 +29,2 @@ "author": "Damian Tarnawski @thetarnav <gthetarnav@gmail.com>", | ||
| "type": "module", | ||
| "main": "./dist/index.cjs", | ||
| "module": "./dist/index.js", | ||
@@ -35,9 +34,6 @@ "types": "./dist/index.d.ts", | ||
| "exports": { | ||
| "@solid-primitives/source": "./src/index.ts", | ||
| "import": { | ||
| "types": "./dist/index.d.ts", | ||
| "default": "./dist/index.js" | ||
| }, | ||
| "require": { | ||
| "types": "./dist/index.d.cts", | ||
| "default": "./dist/index.cjs" | ||
| } | ||
@@ -52,3 +48,3 @@ }, | ||
| "dependencies": { | ||
| "@solid-primitives/utils": "^6.2.3" | ||
| "@solid-primitives/utils": "^6.3.0" | ||
| }, | ||
@@ -55,0 +51,0 @@ "peerDependencies": { |
+0
-1
@@ -7,3 +7,2 @@ <p> | ||
| [](https://turborepo.org/) | ||
| [](https://bundlephobia.com/package/@solid-primitives/destructure) | ||
@@ -10,0 +9,0 @@ [](https://www.npmjs.com/package/@solid-primitives/destructure) |
| 'use strict'; | ||
| var solidJs = require('solid-js'); | ||
| var utils = require('@solid-primitives/utils'); | ||
| // src/index.ts | ||
| var isReactiveObject = (value) => typeof value === "object" && value !== null; | ||
| function createProxyCache(obj, get) { | ||
| return new Proxy( | ||
| {}, | ||
| { | ||
| get: (target, key) => { | ||
| if (key === Symbol.iterator || key === "length") | ||
| return Reflect.get(obj, key); | ||
| const saved = Reflect.get(target, key); | ||
| if (saved) | ||
| return saved; | ||
| const value = get(key); | ||
| Reflect.set(target, key, value); | ||
| return value; | ||
| }, | ||
| set: () => false | ||
| } | ||
| ); | ||
| } | ||
| function destructure(source, options) { | ||
| const config = options ?? {}; | ||
| const memo = config.memo ?? typeof source === "function"; | ||
| const getter = typeof source === "function" ? (key) => () => source()[key] : (key) => () => source[key]; | ||
| const obj = utils.access(source); | ||
| if (config.lazy) { | ||
| const owner = solidJs.getOwner(); | ||
| return createProxyCache(obj, (key) => { | ||
| const calc = getter(key); | ||
| if (config.deep && isReactiveObject(obj[key])) | ||
| return solidJs.runWithOwner(owner, () => destructure(calc, { ...config, memo })); | ||
| return memo ? solidJs.runWithOwner(owner, () => solidJs.createMemo(calc, void 0, options)) : calc; | ||
| }); | ||
| } | ||
| const result = Array.isArray(obj) ? [] : {}; | ||
| for (const [key, value] of Object.entries(obj)) { | ||
| const calc = getter(key); | ||
| if (config.deep && isReactiveObject(value)) | ||
| result[key] = destructure(calc, { ...config, memo }); | ||
| else | ||
| result[key] = memo ? solidJs.createMemo(calc, void 0, options) : calc; | ||
| } | ||
| return result; | ||
| } | ||
| exports.destructure = destructure; |
| 'use strict'; | ||
| var solidJs = require('solid-js'); | ||
| var utils = require('@solid-primitives/utils'); | ||
| // src/index.ts | ||
| var isReactiveObject = (value) => typeof value === "object" && value !== null; | ||
| function createProxyCache(obj, get) { | ||
| return new Proxy( | ||
| {}, | ||
| { | ||
| get: (target, key) => { | ||
| if (key === Symbol.iterator || key === "length") | ||
| return Reflect.get(obj, key); | ||
| const saved = Reflect.get(target, key); | ||
| if (saved) | ||
| return saved; | ||
| const value = get(key); | ||
| Reflect.set(target, key, value); | ||
| return value; | ||
| }, | ||
| set: () => false | ||
| } | ||
| ); | ||
| } | ||
| function destructure(source, options) { | ||
| const config = options ?? {}; | ||
| const memo = config.memo ?? typeof source === "function"; | ||
| const getter = typeof source === "function" ? (key) => () => source()[key] : (key) => () => source[key]; | ||
| const obj = utils.access(source); | ||
| if (config.lazy) { | ||
| const owner = solidJs.getOwner(); | ||
| return createProxyCache(obj, (key) => { | ||
| const calc = getter(key); | ||
| if (config.deep && isReactiveObject(obj[key])) | ||
| return solidJs.runWithOwner(owner, () => destructure(calc, { ...config, memo })); | ||
| return memo ? solidJs.runWithOwner(owner, () => solidJs.createMemo(calc, void 0, options)) : calc; | ||
| }); | ||
| } | ||
| const result = Array.isArray(obj) ? [] : {}; | ||
| for (const [key, value] of Object.entries(obj)) { | ||
| const calc = getter(key); | ||
| if (config.deep && isReactiveObject(value)) | ||
| result[key] = destructure(calc, { ...config, memo }); | ||
| else | ||
| result[key] = memo ? solidJs.createMemo(calc, void 0, options) : calc; | ||
| } | ||
| return result; | ||
| } | ||
| exports.destructure = destructure; |
| import { MemoOptions, Accessor } from 'solid-js'; | ||
| import { Values, AnyFunction, MaybeAccessor, AnyObject } from '@solid-primitives/utils'; | ||
| type ReactiveSource = [] | any[] | AnyObject; | ||
| type DestructureOptions<T extends ReactiveSource> = MemoOptions<Values<T>> & { | ||
| memo?: boolean; | ||
| lazy?: boolean; | ||
| deep?: boolean; | ||
| }; | ||
| type Spread<T extends ReactiveSource> = { | ||
| readonly [K in keyof T]: Accessor<T[K]>; | ||
| }; | ||
| type DeepSpread<T extends ReactiveSource> = { | ||
| readonly [K in keyof T]: T[K] extends ReactiveSource ? T[K] extends AnyFunction ? Accessor<T[K]> : DeepSpread<T[K]> : Accessor<T[K]>; | ||
| }; | ||
| type Destructure<T extends ReactiveSource> = { | ||
| readonly [K in keyof T]-?: Accessor<T[K]>; | ||
| }; | ||
| type DeepDestructure<T extends ReactiveSource> = { | ||
| readonly [K in keyof T]-?: T[K] extends ReactiveSource ? T[K] extends AnyFunction ? Accessor<T[K]> : DeepDestructure<T[K]> : Accessor<T[K]>; | ||
| }; | ||
| /** | ||
| * Destructures an reactive object *(e.g. store or component props)* or a signal of one into a tuple/map of signals for each object key. | ||
| * @param source reactive object or signal returning one | ||
| * @param options memo options + primitive configuration: | ||
| * - `memo` - wraps accessors in `createMemo`, making each property update independently. *(enabled by default for signal source)* | ||
| * - `lazy` - property accessors are created on key read. enable if you want to only a subset of source properties, or use properties initially missing | ||
| * - `deep` - destructure nested objects | ||
| * @returns object of the same keys as the source, but with values turned into accessors. | ||
| * @example // spread tuples | ||
| * const [first, second, third] = destructure(() => [1,2,3]) | ||
| * first() // => 1 | ||
| * second() // => 2 | ||
| * third() // => 3 | ||
| * @example // spread objects | ||
| * const { name, age } = destructure({ name: "John", age: 36 }) | ||
| * name() // => "John" | ||
| * age() // => 36 | ||
| */ | ||
| declare function destructure<T extends ReactiveSource, O extends DestructureOptions<T>>(source: MaybeAccessor<T>, options?: O): O extends { | ||
| lazy: true; | ||
| deep: true; | ||
| } ? DeepDestructure<T> : O["lazy"] extends true ? Destructure<T> : O["deep"] extends true ? DeepSpread<T> : Spread<T>; | ||
| export { DeepDestructure, DeepSpread, Destructure, DestructureOptions, Spread, destructure }; |
12826
-26.33%5
-37.5%111
-40.32%169
-0.59%