fix: 修复关闭SSH终端标签页时会话状态未更新的问题

This commit is contained in:
2026-04-18 02:35:38 +08:00
commit 6e2e2f9387
43467 changed files with 5489040 additions and 0 deletions
+21
View File
@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2021 Solid Primitives Working Group
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
+120
View File
@@ -0,0 +1,120 @@
<p>
<img width="100%" src="https://assets.solidjs.com/banner?type=Primitives&background=tiles&project=Utils" alt="Solid Primitives Utils">
</p>
# @solid-primitives/utils
Solid Primitives Utilities is a support and helper package for a number of primitives in our library. Please free to augment or centralize useful utilities and methods in this package for sharing.
## Installation
```bash
npm install @solid-primitives/utils
# or
pnpm add @solid-primitives/utils
# or
yarn add @solid-primitives/utils
```
## Immutable helpers
Functional programming helpers for making non-mutating changes to data. Keeping it immutable. Useful for updating signals.
```ts
import { pick } from "@solid-primitives/utils/immutable";
const original = { foo: 123, bar: "baz" };
const newObj = pick(original, "foo");
original; // { foo: 123, bar: "baz" }
newObj; // { foo: 123 }
```
Use it for changing signals:
```ts
import { push, update } from "@solid-primitives/utils/immutable";
const [list, setList] = createSignal([1, 2, 3]);
setList(p => push(p, 4));
const [user, setUser] = createSignal({
name: "John",
street: { name: "Kingston Cei", number: 24 },
});
setUser(p => update(p, "street", "number", 64));
```
## List of functions:
### Copying
- **`shallowArrayCopy`** - make shallow copy of an array
- **`shallowObjectCopy`** - make shallow copy of an object
- **`shallowCopy`** - make shallow copy of an array/object
- **`withArrayCopy`** - apply mutations to the an array without changing the original
- **`withObjectCopy`** - apply mutations to the an object without changing the original
- **`withCopy`** - apply mutations to the an object/array without changing the original
### Array
- **`push`** - non-mutating `Array.prototype.push()`
- **`drop`** - non-mutating function that drops n items from the array start
- **`dropRight`** - non-mutating function that drops n items from the array end
- **`filterOut`** - standalone `Array.prototype.filter()` that filters out passed item
- **`filter`** - standalone `Array.prototype.filter()`
- **`sort`** - non-mutating `Array.prototype.sort()` as a standalone function
- **`sortBy`** - Sort an array by object key, or multiple keys
- **`map`** - standalone `Array.prototype.map()` function
- **`slice`** - standalone `Array.prototype.slice()` function
- **`splice`** - non-mutating `Array.prototype.splice()` as a standalone function
- **`fill`** - non-mutating `Array.prototype.fill()` as a standalone function
- **`concat`** - Creates a new array concatenating array with any additional arrays and/or values.
- **`remove`** - Remove item from array
- **`removeItems`** - Remove multiple items from an array
- **`flatten`** - Flattens a nested array into a one-level array
- **`filterInstance`** - Flattens a nested array into a one-level array
- **`filterOutInstance`** - Flattens a nested array into a one-level array
### Object
- **`omit`** - Create a new subset object without the provided keys
- **`pick`** - Create a new subset object with only the provided keys
- **`split`** - Split object into multiple subset objects.
- **`merge`** - Merges multiple objects into a single one.
### Object/Array
- **`get`** - Get a single property value of an object by specifying a path to it.
- **`update`** - Change single value in an object by key, or series of recursing keys.
### Number
- **`add`** - `a + b + c + ...` _(works for numbers or strings)_
- **`substract`** - `a - b - c - ...`
- **`multiply`** - `a * b * c * ...`
- **`divide`** - `a / b / c / ...`
- **`power`** - `a ** b ** c ** ...`
- **`clamp`** - clamp a number value between two other values
## String transforms
`(string) => T` transform functions for converting raw string data into typed values. Useful as the `transform` option for SSE, WebSocket, and similar streaming primitives.
```ts
import { json, ndjson, safe } from "@solid-primitives/utils";
const { data } = createSSE<Event>(url, { transform: json });
const { data } = createSSE<Event[]>(url, { transform: ndjson });
const { data } = createSSE<Event>(url, { transform: safe(json) });
```
- **`json`** - Parse a string as a single JSON value
- **`ndjson`** - Parse newline-delimited JSON (NDJSON / JSON Lines) into an array
- **`lines`** - Split a string into a `string[]` by newline, filtering empty lines
- **`number`** - Parse a string as a number via `Number()`
- **`safe(transform, fallback?)`** - Wrap any transform in a `try/catch`; returns `fallback` instead of throwing
- **`pipe(a, b)`** - Compose two transforms into one
## Changelog
See [CHANGELOG.md](./CHANGELOG.md)
+112
View File
@@ -0,0 +1,112 @@
import { type AnyClass, type ItemsOf, type Many } from "../index.js";
import type { FlattenArray, MappingFn, Predicate } from "./types.js";
/**
* non-mutating `Array.prototype.push()`
* @returns changed array copy
*/
export declare const push: <T>(list: readonly T[], ...items: T[]) => T[];
/**
* non-mutating function that drops n items from the array start.
* @returns changed array copy
*
* @example
* ```ts
* const newList = drop([1,2,3])
* newList // => [2,3]
*
* const newList = drop([1,2,3], 2)
* newList // => [3]
* ```
*/
export declare const drop: <T>(list: T[], n?: number) => T[];
/**
* non-mutating function that drops n items from the array end.
* @returns changed array copy
*
* @example
* ```ts
* const newList = dropRight([1,2,3])
* newList // => [1,2]
*
* const newList = dropRight([1,2,3], 2)
* newList // => [1]
* ```
*/
export declare const dropRight: <T>(list: T[], n?: number) => T[];
/**
* standalone `Array.prototype.filter()` that filters out passed item
* @returns changed array copy
*/
export declare const filterOut: <T>(list: readonly T[], item: T) => T[] & {
removed: number;
};
/**
* standalone `Array.prototype.filter()`
* @returns changed array copy
*/
export declare function filter<T>(list: readonly T[], predicate: Predicate<T>): T[] & {
removed: number;
};
/**
* non-mutating `Array.prototype.sort()` as a standalone function
* @returns changed array copy
*/
export declare const sort: <T>(list: T[], compareFn?: (a: T, b: T) => number) => T[];
/**
* standalone `Array.prototype.map()` function
*/
export declare const map: <T, V>(list: readonly T[], mapFn: MappingFn<T, V>) => V[];
/**
* standalone `Array.prototype.slice()` function
*/
export declare const slice: <T>(list: readonly T[], start?: number, end?: number) => T[];
/**
* non-mutating `Array.prototype.splice()` as a standalone function
* @returns changed array copy
*/
export declare const splice: <T>(list: readonly T[], start: number, deleteCount?: number, ...items: T[]) => T[];
/**
* non-mutating `Array.prototype.fill()` as a standalone function
* @returns changed array copy
*/
export declare const fill: <T>(list: readonly T[], value: T, start?: number, end?: number) => T[];
/**
* Creates a new array concatenating array with any additional arrays and/or values.
* @param ...a values or arrays
* @returns new concatenated array
*/
export declare function concat<A extends any[], V extends ItemsOf<A>>(...a: A): Array<V extends any[] ? ItemsOf<V> : V>;
/**
* Remove item from array
* @returns changed array copy
*/
export declare const remove: <T>(list: readonly T[], item: T, ...insertItems: T[]) => T[];
/**
* Remove multiple items from an array
* @returns changed array copy
*/
export declare const removeItems: <T>(list: readonly T[], ...items: T[]) => T[];
/**
* Flattens a nested array into a one-level array
* @returns changed array copy
*/
export declare const flatten: <T extends any[]>(arr: T) => FlattenArray<T>[];
/**
* Sort an array by object key, or multiple keys
* @returns changed array copy
*/
export declare const sortBy: <T>(arr: T[], ...paths: T extends object ? (Many<keyof T> | Many<(item: T) => any>)[] : Many<(item: T) => any>[]) => T[];
/**
* Returns a subset of items that are instances of provided Classes
* @param list list of original items
* @param ...classes list or classes
* @returns changed array copy
*/
export declare const filterInstance: <T, I extends AnyClass[]>(list: readonly T[], ...classes: I) => Extract<T, InstanceType<ItemsOf<I>>>[];
/**
* Returns a subset of items that aren't instances of provided Classes
* @param list list of original items
* @param ...classes list or classes
* @returns changed array copy
*/
export declare const filterOutInstance: <T, I extends AnyClass[]>(list: readonly T[], ...classes: I) => Exclude<T, InstanceType<ItemsOf<I>>>[];
+139
View File
@@ -0,0 +1,139 @@
import { compare, ofClass } from "../index.js";
import { withArrayCopy } from "./copy.js";
import { get } from "./object.js";
/**
* non-mutating `Array.prototype.push()`
* @returns changed array copy
*/
export const push = (list, ...items) => withArrayCopy(list, list => list.push(...items));
/**
* non-mutating function that drops n items from the array start.
* @returns changed array copy
*
* @example
* ```ts
* const newList = drop([1,2,3])
* newList // => [2,3]
*
* const newList = drop([1,2,3], 2)
* newList // => [3]
* ```
*/
export const drop = (list, n = 1) => list.slice(n);
/**
* non-mutating function that drops n items from the array end.
* @returns changed array copy
*
* @example
* ```ts
* const newList = dropRight([1,2,3])
* newList // => [1,2]
*
* const newList = dropRight([1,2,3], 2)
* newList // => [1]
* ```
*/
export const dropRight = (list, n = 1) => list.slice(0, list.length - n);
/**
* standalone `Array.prototype.filter()` that filters out passed item
* @returns changed array copy
*/
export const filterOut = (list, item) => filter(list, i => i !== item);
/**
* standalone `Array.prototype.filter()`
* @returns changed array copy
*/
export function filter(list, predicate) {
const newList = list.filter(predicate);
newList.removed = list.length - newList.length;
return newList;
}
/**
* non-mutating `Array.prototype.sort()` as a standalone function
* @returns changed array copy
*/
export const sort = (list, compareFn) => list.slice().sort(compareFn);
/**
* standalone `Array.prototype.map()` function
*/
export const map = (list, mapFn) => list.map(mapFn);
/**
* standalone `Array.prototype.slice()` function
*/
export const slice = (list, start, end) => list.slice(start, end);
/**
* non-mutating `Array.prototype.splice()` as a standalone function
* @returns changed array copy
*/
export const splice = (list, start, deleteCount = 0, ...items) => withArrayCopy(list, list => list.splice(start, deleteCount, ...items));
/**
* non-mutating `Array.prototype.fill()` as a standalone function
* @returns changed array copy
*/
export const fill = (list, value, start, end) => list.slice().fill(value, start, end);
/**
* Creates a new array concatenating array with any additional arrays and/or values.
* @param ...a values or arrays
* @returns new concatenated array
*/
export function concat(...a) {
const result = [];
for (const i in a) {
Array.isArray(a[i]) ? result.push(...a[i]) : result.push(a[i]);
}
return result;
}
/**
* Remove item from array
* @returns changed array copy
*/
export const remove = (list, item, ...insertItems) => {
const index = list.indexOf(item);
return splice(list, index, 1, ...insertItems);
};
/**
* Remove multiple items from an array
* @returns changed array copy
*/
export const removeItems = (list, ...items) => {
const res = [];
for (let i = 0; i < list.length; i++) {
const item = list[i];
const ii = items.indexOf(item);
if (ii !== -1)
items.splice(ii, 1);
else
res.push(item);
}
return res;
};
/**
* Flattens a nested array into a one-level array
* @returns changed array copy
*/
export const flatten = (arr) => arr.reduce((flat, next) => flat.concat(Array.isArray(next) ? flatten(next) : next), []);
/**
* Sort an array by object key, or multiple keys
* @returns changed array copy
*/
export const sortBy = (arr, ...paths) => flatten(paths).reduce((source, path) => sort(source, (a, b) => typeof path === "function"
? compare(path(a), path(b))
: compare(get(a, path), get(b, path))), arr);
/**
* Returns a subset of items that are instances of provided Classes
* @param list list of original items
* @param ...classes list or classes
* @returns changed array copy
*/
export const filterInstance = (list, ...classes) => (classes.length === 1
? list.filter(item => ofClass(item, classes[0]))
: list.filter(item => item && classes.some(c => ofClass(item, c))));
/**
* Returns a subset of items that aren't instances of provided Classes
* @param list list of original items
* @param ...classes list or classes
* @returns changed array copy
*/
export const filterOutInstance = (list, ...classes) => (classes.length === 1
? list.filter(item => item && !ofClass(item, classes[0]))
: list.filter(item => item && !classes.some(c => ofClass(item, c))));
+27
View File
@@ -0,0 +1,27 @@
/** make shallow copy of an array */
export declare const shallowArrayCopy: <T>(array: readonly T[]) => T[];
/** make shallow copy of an object */
export declare const shallowObjectCopy: <T extends object>(object: T) => T;
/** make shallow copy of an array/object */
export declare const shallowCopy: <T extends object>(source: T) => T;
/**
* apply mutations to the an array without changing the original
* @param array original array
* @param mutator function applying mutations to the copy of source
* @returns changed array copy
*/
export declare const withArrayCopy: <T>(array: readonly T[], mutator: (copy: T[]) => void) => T[];
/**
* apply mutations to the an object without changing the original
* @param object original object
* @param mutator function applying mutations to the copy of source
* @returns changed object copy
*/
export declare const withObjectCopy: <T extends object>(object: T, mutator: (copy: T) => void) => T;
/**
* apply mutations to the an object/array without changing the original
* @param source original object
* @param mutator function applying mutations to the copy of source
* @returns changed object copy
*/
export declare const withCopy: <T extends object>(source: T, mutator: (copy: T) => void) => T;
+37
View File
@@ -0,0 +1,37 @@
/** make shallow copy of an array */
export const shallowArrayCopy = (array) => array.slice();
/** make shallow copy of an object */
export const shallowObjectCopy = (object) => Object.assign({}, object);
/** make shallow copy of an array/object */
export const shallowCopy = (source) => Array.isArray(source) ? shallowArrayCopy(source) : shallowObjectCopy(source);
/**
* apply mutations to the an array without changing the original
* @param array original array
* @param mutator function applying mutations to the copy of source
* @returns changed array copy
*/
export const withArrayCopy = (array, mutator) => {
const copy = shallowArrayCopy(array);
mutator(copy);
return copy;
};
/**
* apply mutations to the an object without changing the original
* @param object original object
* @param mutator function applying mutations to the copy of source
* @returns changed object copy
*/
export const withObjectCopy = (object, mutator) => {
const copy = shallowObjectCopy(object);
mutator(copy);
return copy;
};
/**
* apply mutations to the an object/array without changing the original
* @param source original object
* @param mutator function applying mutations to the copy of source
* @returns changed object copy
*/
export const withCopy = (source, mutator) => Array.isArray(source)
? withArrayCopy(source, mutator)
: withObjectCopy(source, mutator);
+6
View File
@@ -0,0 +1,6 @@
export * from "./copy.js";
export * from "./number.js";
export * from "./update.js";
export * from "./object.js";
export * from "./array.js";
export * from "./types.js";
+6
View File
@@ -0,0 +1,6 @@
export * from "./copy.js";
export * from "./number.js";
export * from "./update.js";
export * from "./object.js";
export * from "./array.js";
export * from "./types.js";
+13
View File
@@ -0,0 +1,13 @@
/** `a + b + c + ...` */
export declare function add(...a: number[]): number;
export declare function add(...a: string[]): string;
/** `a - b - c - ...` */
export declare const substract: (a: number, ...b: number[]) => number;
/** `a * b * c * ...` */
export declare const multiply: (a: number, ...b: number[]) => number;
/** `a / b / c / ...` */
export declare const divide: (a: number, ...b: number[]) => number;
/** `a ** b ** c ** ...` */
export declare const power: (a: number, ...b: number[]) => number;
/** clamp a number value between two other values */
export declare const clamp: (n: number, min: number, max: number) => number;
+37
View File
@@ -0,0 +1,37 @@
export function add(...a) {
let r = 0;
for (const n of a) {
r += n;
}
return r;
}
/** `a - b - c - ...` */
export const substract = (a, ...b) => {
for (const n of b) {
a -= n;
}
return a;
};
/** `a * b * c * ...` */
export const multiply = (a, ...b) => {
for (const n of b) {
a *= n;
}
return a;
};
/** `a / b / c / ...` */
export const divide = (a, ...b) => {
for (const n of b) {
a /= n;
}
return a;
};
/** `a ** b ** c ** ...` */
export const power = (a, ...b) => {
for (const n of b) {
a = a ** n;
}
return a;
};
/** clamp a number value between two other values */
export const clamp = (n, min, max) => Math.min(max, Math.max(min, n));
+63
View File
@@ -0,0 +1,63 @@
import { type Modify } from "../index.js";
/**
* Create a new subset object without the provided keys
*
* @example
* ```ts
* const newObject = omit({ a:"foo", b:"bar", c: "baz" }, 'a', 'b')
* newObject // => { c: "baz" }
* ```
*/
export declare const omit: <O extends object, K extends keyof O>(object: O, ...keys: K[]) => Omit<O, K>;
/**
* Create a new subset object with only the provided keys
*
* @example
* ```ts
* const newObject = pick({ a:"foo", b:"bar", c: "baz" }, 'a', 'b')
* newObject // => { a:"foo", b:"bar" }
* ```
*/
export declare const pick: <O extends object, K extends keyof O>(object: O, ...keys: K[]) => Pick<O, K>;
/**
* Get a single property value of an object by specifying a path to it.
*/
export declare function get<O extends object, K extends keyof O>(obj: O, key: K): O[K];
export declare function get<O extends object, K1 extends keyof O, K2 extends keyof O[K1]>(obj: O, k1: K1, k2: K2): O[K1][K2];
export declare function get<O extends object, K1 extends keyof O, K2 extends keyof O[K1], K3 extends keyof O[K1][K2]>(obj: O, k1: K1, k2: K2, k3: K3): O[K1][K2][K3];
export declare function get<O extends object, K1 extends keyof O, K2 extends keyof O[K1], K3 extends keyof O[K1][K2], K4 extends keyof O[K1][K2][K3]>(obj: O, k1: K1, k2: K2, k3: K3, k4: K4): O[K1][K2][K3][K4];
export declare function get<O extends object, K1 extends keyof O, K2 extends keyof O[K1], K3 extends keyof O[K1][K2], K4 extends keyof O[K1][K2][K3], K5 extends keyof O[K1][K2][K3][K4]>(obj: O, k1: K1, k2: K2, k3: K3, k4: K4, k5: K5): O[K1][K2][K3][K4][K5];
export declare function get<O extends object, K1 extends keyof O, K2 extends keyof O[K1], K3 extends keyof O[K1][K2], K4 extends keyof O[K1][K2][K3], K5 extends keyof O[K1][K2][K3][K4], K6 extends keyof O[K1][K2][K3][K4][K5]>(obj: O, k1: K1, k2: K2, k3: K3, k4: K4, k5: K5, k6: K6): O[K1][K2][K3][K4][K5][K6];
/**
* Split object properties by keys into multiple object copies with a subset of selected properties.
*
* @param object original object
* @param ...keys keys to pick from the source, or multiple arrays of keys *(for splitting into more than 2 objects)*
* ```ts
* (keyof object)[][] | (keyof object)[]
* ```
* @returns array of subset objects
*/
export declare function split<T extends object, K extends keyof T>(object: T, ...keys: K[]): [Pick<T, K>, Omit<T, K>];
export declare function split<T extends object, K1 extends keyof T, K2 extends keyof T>(object: T, ...keys: [K1[], K2[]]): [Pick<T, K1>, Pick<T, K2>, Omit<T, K1 | K2>];
export declare function split<T extends object, K1 extends keyof T, K2 extends keyof T, K3 extends keyof T>(object: T, ...keys: [K1[], K2[], K3[]]): [Pick<T, K1>, Pick<T, K2>, Pick<T, K3>, Omit<T, K1 | K2 | K3>];
export declare function split<T extends object, K1 extends keyof T, K2 extends keyof T, K3 extends keyof T, K4 extends keyof T>(object: T, ...keys: [K1[], K2[], K3[], K4[]]): [Pick<T, K1>, Pick<T, K2>, Pick<T, K3>, Pick<T, K4>, Omit<T, K1 | K2 | K3 | K4>];
export declare function split<T extends object, K1 extends keyof T, K2 extends keyof T, K3 extends keyof T, K4 extends keyof T, K5 extends keyof T>(object: T, ...keys: [K1[], K2[], K3[], K4[], K5[]]): [
Pick<T, K1>,
Pick<T, K2>,
Pick<T, K3>,
Pick<T, K4>,
Pick<T, K5>,
Omit<T, K1 | K2 | K3 | K4 | K5>
];
/**
* Merges multiple objects into a single one. Only the first level of properties is merged. An alternative to `{ ...a, ...b, ...c }`.
* @param ...objects objects to merge
* @example
* const d = merge(a, b, c)
*/
export declare function merge<A extends object, B extends object>(a: A, b: B): Modify<A, B>;
export declare function merge<A extends object, B extends object, C extends object>(a: A, b: B, c: C): Modify<Modify<A, B>, C>;
export declare function merge<A extends object, B extends object, C extends object, D extends object>(a: A, b: B, c: C, d: D): Modify<Modify<Modify<A, B>, C>, D>;
export declare function merge<A extends object, B extends object, C extends object, D extends object, E extends object>(a: A, b: B, c: C, d: D, e: E): Modify<Modify<Modify<Modify<A, B>, C>, D>, E>;
export declare function merge<A extends object, B extends object, C extends object, D extends object, E extends object, F extends object>(a: A, b: B, c: C, d: D, e: E, f: F): Modify<Modify<Modify<Modify<Modify<A, B>, C>, D>, E>, F>;
+54
View File
@@ -0,0 +1,54 @@
import { withObjectCopy, shallowObjectCopy } from "./copy.js";
import {} from "../index.js";
/**
* Create a new subset object without the provided keys
*
* @example
* ```ts
* const newObject = omit({ a:"foo", b:"bar", c: "baz" }, 'a', 'b')
* newObject // => { c: "baz" }
* ```
*/
export const omit = (object, ...keys) => withObjectCopy(object, object => keys.forEach(key => delete object[key]));
/**
* Create a new subset object with only the provided keys
*
* @example
* ```ts
* const newObject = pick({ a:"foo", b:"bar", c: "baz" }, 'a', 'b')
* newObject // => { a:"foo", b:"bar" }
* ```
*/
export const pick = (object, ...keys) => keys.reduce((n, k) => {
if (k in object)
n[k] = object[k];
return n;
}, {});
export function get(obj, ...keys) {
let res = obj;
for (const key of keys) {
res = res[key];
}
return res;
}
export function split(object, ...list) {
const _list = (typeof list[0] === "string" ? [list] : list);
const copy = shallowObjectCopy(object);
const result = [];
for (let i = 0; i < _list.length; i++) {
const keys = _list[i];
result.push({});
for (const key of keys) {
result[i][key] = copy[key];
delete copy[key];
}
}
return [...result, copy];
}
export function merge(...objects) {
const result = {};
for (const obj of objects) {
Object.assign(result, obj);
}
return result;
}
+7
View File
@@ -0,0 +1,7 @@
import { type ItemsOf } from "../index.js";
export type Predicate<T> = (item: T, index: number, array: readonly T[]) => boolean;
export type MappingFn<T, V> = (item: T, index: number, array: readonly T[]) => V;
export type FlattenArray<T> = T extends any[] ? FlattenArray<ItemsOf<T>> : T;
export type ModifyValue<O, K extends keyof O, V> = Omit<O, K> & {
[key in K]: V;
};
+1
View File
@@ -0,0 +1 @@
import {} from "../index.js";
+30
View File
@@ -0,0 +1,30 @@
import { type ModifyValue } from "./types.js";
export type UpdateSetter<O, K extends keyof O, V> = V | ((prev: O[K]) => V);
export type Update = {
<O extends object, K0 extends keyof O, K1 extends keyof O[K0], K2 extends keyof O[K0][K1], K3 extends keyof O[K0][K1][K2], K4 extends keyof O[K0][K1][K2][K3], V>(object: O, k0: K0, k1: K1, k2: K2, k3: K3, k4: K4, setter: UpdateSetter<O[K0][K1][K2][K3], K4, V>): ModifyValue<O, K0, ModifyValue<O[K0], K1, ModifyValue<O[K0][K1], K2, ModifyValue<O[K0][K1][K2], K3, ModifyValue<O[K0][K1][K2][K3], K4, V>>>>>;
<O extends object, K0 extends keyof O, K1 extends keyof O[K0], K2 extends keyof O[K0][K1], K3 extends keyof O[K0][K1][K2], V>(object: O, k0: K0, k1: K1, k2: K2, k3: K3, setter: UpdateSetter<O[K0][K1][K2], K3, V>): ModifyValue<O, K0, ModifyValue<O[K0], K1, ModifyValue<O[K0][K1], K2, ModifyValue<O[K0][K1][K2], K3, V>>>>;
<O extends object, K0 extends keyof O, K1 extends keyof O[K0], K2 extends keyof O[K0][K1], V>(object: O, k0: K0, k1: K1, k2: K2, setter: UpdateSetter<O[K0][K1], K2, V>): ModifyValue<O, K0, ModifyValue<O[K0], K1, ModifyValue<O[K0][K1], K2, V>>>;
<O extends object, K0 extends keyof O, K1 extends keyof O[K0], V>(object: O, k0: K0, k1: K1, setter: UpdateSetter<O[K0], K1, V>): ModifyValue<O, K0, ModifyValue<O[K0], K1, V>>;
<O extends object, K extends keyof O, V>(object: O, key: K, setter: UpdateSetter<O, K, V>): ModifyValue<O, K, V>;
};
/**
* Change single value in an object by key. Allows accessign nested objects by passing multiple keys.
*
* Performs a shallow copy of each accessed object.
*
* @param object original source
* @param ...keys keys of sequential accessed objects
* @param value a value to set in place of a previous one, or a setter function.
* ```ts
* V | ((prev: O[K]) => V)
* ```
* a new value doesn't have to have the same type as the original
* @returns changed copy of the original object
*
* @example
* const original = { foo: { bar: { baz: 123 }}};
* const newObj = update(original, "foo", "bar", "baz", prev => prev + 1)
* original // { foo: { bar: { baz: 123 }}}
* newObj // { foo: { bar: { baz: 124 }}}
*/
export declare const update: Update;
+30
View File
@@ -0,0 +1,30 @@
import { withCopy } from "./copy.js";
import {} from "./types.js";
/**
* Change single value in an object by key. Allows accessign nested objects by passing multiple keys.
*
* Performs a shallow copy of each accessed object.
*
* @param object original source
* @param ...keys keys of sequential accessed objects
* @param value a value to set in place of a previous one, or a setter function.
* ```ts
* V | ((prev: O[K]) => V)
* ```
* a new value doesn't have to have the same type as the original
* @returns changed copy of the original object
*
* @example
* const original = { foo: { bar: { baz: 123 }}};
* const newObj = update(original, "foo", "bar", "baz", prev => prev + 1)
* original // { foo: { bar: { baz: 123 }}}
* newObj // { foo: { bar: { baz: 124 }}}
*/
export const update = (...args) => withCopy(args[0], obj => {
if (args.length > 3)
obj[args[1]] = update(obj[args[1]], ...args.slice(2));
else if (typeof args[2] === "function")
obj[args[1]] = args[2](obj[args[1]]);
else
obj[args[1]] = args[2];
});
+186
View File
@@ -0,0 +1,186 @@
import { onCleanup, createSignal, type Accessor, type AccessorArray, type EffectFunction, type NoInfer, type SignalOptions } from "solid-js";
import { isServer } from "solid-js/web";
import type { AnyClass, MaybeAccessor, MaybeAccessorValue, Noop, AnyObject, AnyFunction } from "./types.js";
export * from "./types.js";
export { isServer };
export declare const isClient: boolean;
export declare const isDev: boolean;
export declare const isProd: boolean;
/** no operation */
export declare const noop: Noop;
export declare const trueFn: () => boolean;
export declare const falseFn: () => boolean;
/** @deprecated use {@link equalFn} from "solid-js" */
export declare const defaultEquals: <T>(a: T, b: T) => boolean;
export declare const EQUALS_FALSE_OPTIONS: {
readonly equals: false;
};
export declare const INTERNAL_OPTIONS: {
readonly internal: true;
};
/**
* Check if the value is an instance of ___
*/
export declare const ofClass: (v: any, c: AnyClass) => boolean;
/** Check if value is typeof "object" or "function" */
export declare function isObject(value: any): value is AnyObject;
export declare const isNonNullable: <T>(i: T) => i is NonNullable<T>;
export declare const filterNonNullable: <T extends readonly unknown[]>(arr: T) => NonNullable<T[number]>[];
export declare const compare: (a: any, b: any) => number;
/**
* Check shallow array equality
*/
export declare const arrayEquals: (a: readonly unknown[], b: readonly unknown[]) => boolean;
/**
* Returns a function that will call all functions in the order they were chained with the same arguments.
*/
export declare function chain<Args extends [] | any[]>(callbacks: {
[Symbol.iterator](): IterableIterator<((...args: Args) => any) | undefined>;
}): (...args: Args) => void;
/**
* Returns a function that will call all functions in the reversed order with the same arguments.
*/
export declare function reverseChain<Args extends [] | any[]>(callbacks: (((...args: Args) => any) | undefined)[]): (...args: Args) => void;
export declare const clamp: (n: number, min: number, max: number) => number;
/**
* Accesses the value of a MaybeAccessor
* @example
* ```ts
* access("foo") // => "foo"
* access(() => "foo") // => "foo"
* ```
*/
export declare const access: <T extends MaybeAccessor<any>>(v: T) => MaybeAccessorValue<T>;
export declare const asArray: <T>(value: T) => (T extends any[] ? T[number] : NonNullable<T>)[];
/**
* Access an array of MaybeAccessors
* @example
* const list = [1, 2, () => 3)] // T: MaybeAccessor<number>[]
* const newList = accessArray(list) // T: number[]
*/
export declare const accessArray: <A extends MaybeAccessor<any>>(list: readonly A[]) => MaybeAccessorValue<A>[];
/**
* Run the function if the accessed value is not `undefined` nor `null`
* @param value
* @param fn
*/
export declare const withAccess: <T, A extends MaybeAccessor<T>, V = MaybeAccessorValue<A>>(value: A, fn: (value: NonNullable<V>) => void) => void;
export declare const asAccessor: <A extends MaybeAccessor<unknown>>(v: A) => Accessor<MaybeAccessorValue<A>>;
/** If value is a function call it with a given arguments otherwise get the value as is */
export declare function accessWith<T>(valueOrFn: T, ...args: T extends AnyFunction ? Parameters<T> : never): T extends AnyFunction ? ReturnType<T> : T;
/**
* Solid's `on` helper, but always defers and returns a provided initial value when if does instead of `undefined`.
*
* @param deps
* @param fn
* @param initialValue
*/
export declare function defer<S, Next extends Prev, Prev = Next>(deps: AccessorArray<S> | Accessor<S>, fn: (input: S, prevInput: S, prev: undefined | NoInfer<Prev>) => Next, initialValue: Next): EffectFunction<undefined | NoInfer<Next>, NoInfer<Next>>;
export declare function defer<S, Next extends Prev, Prev = Next>(deps: AccessorArray<S> | Accessor<S>, fn: (input: S, prevInput: S, prev: undefined | NoInfer<Prev>) => Next, initialValue?: undefined): EffectFunction<undefined | NoInfer<Next>>;
/**
* Get entries of an object
*/
export declare const entries: <T extends object>(obj: T) => [keyof T, T[keyof T]][];
/**
* Get keys of an object
*/
export declare const keys: <T extends object>(object: T) => (keyof T)[];
/**
* Solid's `onCleanup` that doesn't warn in development if used outside of a component.
*/
export declare const tryOnCleanup: typeof onCleanup;
export declare const createCallbackStack: <A0 = void, A1 = void, A2 = void, A3 = void>() => {
push: (...callbacks: ((arg0: A0, arg1: A1, arg2: A2, arg3: A3) => void)[]) => void;
execute: (arg0: A0, arg1: A1, arg2: A2, arg3: A3) => void;
clear: VoidFunction;
};
/**
* Group synchronous function calls.
* @param fn
* @returns `fn`
*/
export declare function createMicrotask<A extends any[] | []>(fn: (...a: A) => void): (...a: A) => void;
/**
* A hydratable version of the {@link createSignal}. It will use the serverValue on the server and the update function on the client. If initialized during hydration it will use serverValue as the initial value and update it once hydration is complete.
*
* @param serverValue initial value of the state on the server
* @param update called once on the client or on hydration to initialize the value
* @param options {@link SignalOptions}
* @returns
* ```ts
* [state: Accessor<T>, setState: Setter<T>]
* ```
* @see {@link createSignal}
*/
export declare function createHydratableSignal<T>(serverValue: T, update: () => T, options?: SignalOptions<T>): ReturnType<typeof createSignal<T>>;
/** @deprecated use {@link createHydratableSignal} instead */
export declare const createHydrateSignal: typeof createHydratableSignal;
/**
* Handle items removed and added to the array by diffing it by refference.
*
* @param current new array instance
* @param prev previous array copy
* @param handleAdded called once for every added item to array
* @param handleRemoved called once for every removed from array
*/
export declare function handleDiffArray<T>(current: readonly T[], prev: readonly T[], handleAdded: (item: T) => void, handleRemoved: (item: T) => void): void;
/**
* Parse a string as a single JSON value.
*
* ```ts
* const { data } = createSSE<{ status: string }>(url, { transform: json });
* ```
*/
export declare const json: <T>(raw: string) => T;
/**
* Parse a string as newline-delimited JSON (NDJSON / JSON Lines).
*
* Each non-empty line is parsed as a separate JSON value and returned as an array.
*
* ```ts
* const { data } = createSSE<TickEvent[]>(url, { transform: ndjson });
* // data() === [{ id: 1, type: "tick" }, { id: 2, type: "tick" }]
* ```
*/
export declare const ndjson: <T>(raw: string) => T[];
/**
* Split a string into individual lines, returning a `string[]`. Empty lines are filtered out.
*
* ```ts
* const { data } = createSSE<string[]>(url, { transform: lines });
* // data() === ["line one", "line two"]
* ```
*/
export declare const lines: (raw: string) => string[];
/**
* Parse a string as a number using `Number()` semantics.
*
* Note: `""` → `0`, non-numeric strings → `NaN`.
*
* ```ts
* const { data } = createSSE<number>(url, { transform: number });
* // data() === 42
* ```
*/
export declare const number: (raw: string) => number;
/**
* Wrap any `(string) => T` transform in a `try/catch`. Returns `fallback`
* (default `undefined`) instead of throwing on malformed input.
*
* ```ts
* const { data } = createSSE<MyEvent>(url, { transform: safe(json) });
* const { data } = createSSE<number>(url, { transform: safe(number, 0) });
* ```
*/
export declare function safe<T>(transform: (raw: string) => T): (raw: string) => T | undefined;
export declare function safe<T>(transform: (raw: string) => T, fallback: T): (raw: string) => T;
/**
* Compose two transforms into one: the output of `a` is passed as the input of `b`.
*
* ```ts
* const { data } = createSSE<RawEvent[]>(url, {
* transform: pipe(ndjson<RawEvent>, rows => rows.filter(r => r.type === "tick")),
* });
* ```
*/
export declare function pipe<A, B>(a: (raw: string) => A, b: (a: A) => B): (raw: string) => B;
+278
View File
@@ -0,0 +1,278 @@
import { getOwner, onCleanup, createSignal, untrack, sharedConfig, onMount, DEV, equalFn, } from "solid-js";
import { isServer } from "solid-js/web";
export * from "./types.js";
//
// GENERAL HELPERS:
//
export { isServer };
export const isClient = !isServer;
export const isDev = isClient && !!DEV;
export const isProd = !isDev;
/** no operation */
export const noop = (() => void 0);
export const trueFn = () => true;
export const falseFn = () => false;
/** @deprecated use {@link equalFn} from "solid-js" */
export const defaultEquals = equalFn;
export const EQUALS_FALSE_OPTIONS = { equals: false };
export const INTERNAL_OPTIONS = { internal: true };
/**
* Check if the value is an instance of ___
*/
export const ofClass = (v, c) => v instanceof c || (v && v.constructor === c);
/** Check if value is typeof "object" or "function" */
export function isObject(value) {
return value !== null && (typeof value === "object" || typeof value === "function");
}
export const isNonNullable = (i) => i != null;
export const filterNonNullable = (arr) => arr.filter(isNonNullable);
export const compare = (a, b) => (a < b ? -1 : a > b ? 1 : 0);
/**
* Check shallow array equality
*/
export const arrayEquals = (a, b) => a === b || (a.length === b.length && a.every((e, i) => e === b[i]));
/**
* Returns a function that will call all functions in the order they were chained with the same arguments.
*/
export function chain(callbacks) {
return (...args) => {
for (const callback of callbacks)
callback && callback(...args);
};
}
/**
* Returns a function that will call all functions in the reversed order with the same arguments.
*/
export function reverseChain(callbacks) {
return (...args) => {
for (let i = callbacks.length - 1; i >= 0; i--) {
const callback = callbacks[i];
callback && callback(...args);
}
};
}
export const clamp = (n, min, max) => Math.min(Math.max(n, min), max);
/**
* Accesses the value of a MaybeAccessor
* @example
* ```ts
* access("foo") // => "foo"
* access(() => "foo") // => "foo"
* ```
*/
export const access = (v) => typeof v === "function" && !v.length ? v() : v;
export const asArray = (value) => Array.isArray(value) ? value : value ? [value] : [];
/**
* Access an array of MaybeAccessors
* @example
* const list = [1, 2, () => 3)] // T: MaybeAccessor<number>[]
* const newList = accessArray(list) // T: number[]
*/
export const accessArray = (list) => list.map(v => access(v));
/**
* Run the function if the accessed value is not `undefined` nor `null`
* @param value
* @param fn
*/
export const withAccess = (value, fn) => {
const _value = access(value);
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
typeof _value != null && fn(_value);
};
export const asAccessor = (v) => (typeof v === "function" ? v : () => v);
/** If value is a function call it with a given arguments otherwise get the value as is */
export function accessWith(valueOrFn, ...args) {
return typeof valueOrFn === "function" ? valueOrFn(...args) : valueOrFn;
}
export function defer(deps, fn, initialValue) {
const isArray = Array.isArray(deps);
let prevInput;
let shouldDefer = true;
return prevValue => {
let input;
if (isArray) {
input = Array(deps.length);
for (let i = 0; i < deps.length; i++)
input[i] = deps[i]();
}
else
input = deps();
if (shouldDefer) {
shouldDefer = false;
prevInput = input;
return initialValue;
}
const result = untrack(() => fn(input, prevInput, prevValue));
prevInput = input;
return result;
};
}
/**
* Get entries of an object
*/
export const entries = Object.entries;
/**
* Get keys of an object
*/
export const keys = Object.keys;
/**
* Solid's `onCleanup` that doesn't warn in development if used outside of a component.
*/
export const tryOnCleanup = isDev
? fn => (getOwner() ? onCleanup(fn) : fn)
: onCleanup;
export const createCallbackStack = () => {
let stack = [];
const clear = () => (stack = []);
return {
push: (...callbacks) => stack.push(...callbacks),
execute(arg0, arg1, arg2, arg3) {
stack.forEach(cb => cb(arg0, arg1, arg2, arg3));
clear();
},
clear,
};
};
/**
* Group synchronous function calls.
* @param fn
* @returns `fn`
*/
export function createMicrotask(fn) {
let calls = 0;
let args;
onCleanup(() => (calls = 0));
return (...a) => {
(args = a), calls++;
queueMicrotask(() => --calls === 0 && fn(...args));
};
}
/**
* A hydratable version of the {@link createSignal}. It will use the serverValue on the server and the update function on the client. If initialized during hydration it will use serverValue as the initial value and update it once hydration is complete.
*
* @param serverValue initial value of the state on the server
* @param update called once on the client or on hydration to initialize the value
* @param options {@link SignalOptions}
* @returns
* ```ts
* [state: Accessor<T>, setState: Setter<T>]
* ```
* @see {@link createSignal}
*/
export function createHydratableSignal(serverValue, update, options) {
if (isServer) {
return createSignal(serverValue, options);
}
if (sharedConfig.context) {
const [state, setState] = createSignal(serverValue, options);
onMount(() => setState(() => update()));
return [state, setState];
}
return createSignal(update(), options);
}
/** @deprecated use {@link createHydratableSignal} instead */
export const createHydrateSignal = createHydratableSignal;
/**
* Handle items removed and added to the array by diffing it by refference.
*
* @param current new array instance
* @param prev previous array copy
* @param handleAdded called once for every added item to array
* @param handleRemoved called once for every removed from array
*/
export function handleDiffArray(current, prev, handleAdded, handleRemoved) {
const currLength = current.length;
const prevLength = prev.length;
let i = 0;
if (!prevLength) {
for (; i < currLength; i++)
handleAdded(current[i]);
return;
}
if (!currLength) {
for (; i < prevLength; i++)
handleRemoved(prev[i]);
return;
}
for (; i < prevLength; i++) {
if (prev[i] !== current[i])
break;
}
let prevEl;
let currEl;
prev = prev.slice(i);
current = current.slice(i);
for (prevEl of prev) {
if (!current.includes(prevEl))
handleRemoved(prevEl);
}
for (currEl of current) {
if (!prev.includes(currEl))
handleAdded(currEl);
}
}
// ─── String transforms ────────────────────────────────────────────────────────
/**
* Parse a string as a single JSON value.
*
* ```ts
* const { data } = createSSE<{ status: string }>(url, { transform: json });
* ```
*/
export const json = (raw) => JSON.parse(raw);
/**
* Parse a string as newline-delimited JSON (NDJSON / JSON Lines).
*
* Each non-empty line is parsed as a separate JSON value and returned as an array.
*
* ```ts
* const { data } = createSSE<TickEvent[]>(url, { transform: ndjson });
* // data() === [{ id: 1, type: "tick" }, { id: 2, type: "tick" }]
* ```
*/
export const ndjson = (raw) => raw
.split("\n")
.filter(line => line !== "")
.map(line => JSON.parse(line));
/**
* Split a string into individual lines, returning a `string[]`. Empty lines are filtered out.
*
* ```ts
* const { data } = createSSE<string[]>(url, { transform: lines });
* // data() === ["line one", "line two"]
* ```
*/
export const lines = (raw) => raw.split("\n").filter(line => line !== "");
/**
* Parse a string as a number using `Number()` semantics.
*
* Note: `""` → `0`, non-numeric strings → `NaN`.
*
* ```ts
* const { data } = createSSE<number>(url, { transform: number });
* // data() === 42
* ```
*/
export const number = (raw) => Number(raw);
export function safe(transform, fallback) {
return (raw) => {
try {
return transform(raw);
}
catch {
return fallback;
}
};
}
/**
* Compose two transforms into one: the output of `a` is passed as the input of `b`.
*
* ```ts
* const { data } = createSSE<RawEvent[]>(url, {
* transform: pipe(ndjson<RawEvent>, rows => rows.filter(r => r.type === "tick")),
* });
* ```
*/
export function pipe(a, b) {
return (raw) => b(a(raw));
}
+89
View File
@@ -0,0 +1,89 @@
import type { Accessor, Setter } from "solid-js";
export type { EffectOptions, OnOptions } from "solid-js";
export type { ResolvedJSXElement, ResolvedChildren } from "solid-js/types/reactive/signal.js";
/**
* Can be single or in an array
*/
export type Many<T> = T | T[];
export type Values<O extends Object> = O[keyof O];
export type Noop = (...a: any[]) => void;
export type Directive<P = true> = (el: Element, props: Accessor<P>) => void;
/**
* Infers the type of the array elements
*/
export type ItemsOf<T> = T extends (infer E)[] ? E : never;
export type ItemsOfMany<T> = T extends any[] ? ItemsOf<T> : T;
export type SetterParam<T> = Parameters<Setter<T>>[0];
/**
* T or a reactive/non-reactive function returning T
*/
export type MaybeAccessor<T> = T | Accessor<T>;
/**
* Accessed value of a MaybeAccessor
* @example
* ```ts
* MaybeAccessorValue<MaybeAccessor<string>>
* // => string
* MaybeAccessorValue<MaybeAccessor<() => string>>
* // => string | (() => string)
* MaybeAccessorValue<MaybeAccessor<string> | Function>
* // => string | void
* ```
*/
export type MaybeAccessorValue<T extends MaybeAccessor<any>> = T extends () => any ? ReturnType<T> : T;
export type OnAccessEffectFunction<S, Prev, Next extends Prev = Prev> = (input: AccessReturnTypes<S>, prevInput: AccessReturnTypes<S>, v: Prev) => Next;
export type AccessReturnTypes<S> = S extends MaybeAccessor<any>[] ? {
[I in keyof S]: AccessReturnTypes<S[I]>;
} : MaybeAccessorValue<S>;
/** Allows to make shallow overwrites to an interface */
export type Modify<T, R> = Omit<T, keyof R> & R;
/** Allows to make nested overwrites to an interface */
export type ModifyDeep<A extends AnyObject, B extends DeepPartialAny<A>> = {
[K in keyof A]: B[K] extends never ? A[K] : B[K] extends AnyObject ? ModifyDeep<A[K], B[K]> : B[K];
} & (A extends AnyObject ? Omit<B, keyof A> : A);
/** Makes each property optional and turns each leaf property into any, allowing for type overrides by narrowing any. */
export type DeepPartialAny<T> = {
[P in keyof T]?: T[P] extends AnyObject ? DeepPartialAny<T[P]> : any;
};
/** Removes the `[...list]` functionality */
export type NonIterable<T> = T & {
[Symbol.iterator]: never;
};
/** Get the required keys of an object */
export type RequiredKeys<T> = keyof {
[K in keyof T as T extends {
[_ in K]: unknown;
} ? K : never]: 0;
};
/** Remove the first item of a tuple [1, 2, 3, 4] => [2, 3, 4] */
export type Tail<T extends any[]> = ((...t: T) => void) extends (x: any, ...u: infer U) => void ? U : never;
/** `A | B => A & B` */
export type UnionToIntersection<U> = (U extends any ? (k: U) => void : never) extends (k: infer I) => void ? I : never;
export type ExtractIfPossible<T, U> = Extract<T, U> extends never ? U : Extract<T, U>;
export type AnyObject = Record<PropertyKey, any>;
export type AnyStatic = [] | any[] | AnyObject;
export type AnyFunction = (...args: any[]) => any;
export type AnyClass = abstract new (...args: any) => any;
export type PrimitiveValue = PropertyKey | boolean | bigint | null | undefined;
export type FalsyValue = false | 0 | "" | null | undefined;
export type Truthy<T> = Exclude<T, FalsyValue>;
export type Falsy<T> = Extract<T, FalsyValue>;
export type Position = {
x: number;
y: number;
};
export type Size = {
width: number;
height: number;
};
/** Unwraps the type definition of an object, making it more readable */
export type Simplify<T> = T extends object ? {
[K in keyof T]: T[K];
} : T;
/** Unboxes type definition, making it more readable */
export type UnboxLazy<T> = T extends () => infer U ? U : T;
type RawNarrow<T> = (T extends [] ? [] : never) | (T extends string | number | bigint | boolean ? T : never) | {
[K in keyof T]: T[K] extends Function ? T[K] : RawNarrow<T[K]>;
};
export type Narrow<T> = T extends [] ? T : RawNarrow<T>;
export type NoInfer<T> = [T][T extends any ? 0 : never];
+1
View File
@@ -0,0 +1 @@
export {};
+69
View File
@@ -0,0 +1,69 @@
{
"name": "@solid-primitives/utils",
"version": "6.4.0",
"description": "A bunch of reactive utility types and functions, for building primitives with Solid.js",
"author": "Damian Tarnawski @thetarnav <gthetarnav@gmail.com>",
"contributors": [
"Tom Pichaud <dev.tompichaud@icloud.com>"
],
"license": "MIT",
"homepage": "https://github.com/solidjs-community/solid-primitives/tree/main/packages/utils#readme",
"repository": {
"type": "git",
"url": "git+https://github.com/solidjs-community/solid-primitives.git"
},
"bugs": {
"url": "https://github.com/solidjs-community/solid-primitives/issues"
},
"private": false,
"sideEffects": false,
"files": [
"dist"
],
"type": "module",
"module": "./dist/index.js",
"types": "./dist/index.d.ts",
"browser": {},
"exports": {
".": {
"import": {
"@solid-primitives/source": "./src/index.ts",
"types": "./dist/index.d.ts",
"default": "./dist/index.js"
}
},
"./immutable": {
"import": {
"@solid-primitives/source": "./src/immutable/index.ts",
"types": "./dist/immutable/index.d.ts",
"default": "./dist/immutable/index.js"
}
}
},
"typesVersions": {
"*": {
"immutable": [
"./dist/immutable/index.d.ts"
]
}
},
"keywords": [
"utilities",
"reactivity",
"solid",
"primitives"
],
"peerDependencies": {
"solid-js": "^1.6.12"
},
"devDependencies": {
"solid-js": "^1.9.7"
},
"scripts": {
"dev": "node --import=@nothing-but/node-resolve-ts --experimental-transform-types ../../scripts/dev.ts",
"build": "node --import=@nothing-but/node-resolve-ts --experimental-transform-types ../../scripts/build.ts",
"vitest": "vitest -c ../../configs/vitest.config.ts",
"test": "pnpm run vitest",
"test:ssr": "pnpm run vitest --mode ssr"
}
}