Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@solid-primitives/storage

Package Overview
Dependencies
Maintainers
2
Versions
45
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@solid-primitives/storage - npm Package Compare versions

Comparing version 1.0.4 to 1.0.7

dist/chunk-INHFJDUZ.js

89

dist/cookies.js

@@ -1,78 +0,13 @@

import { addClearMethod } from "./tools";
import { createStorage, createStorageSignal } from "./storage";
const serializeCookieOptions = (options) => {
if (!options) {
return "";
}
let memo = "";
for (const key in options) {
if (!options.hasOwnProperty(key)) {
continue;
}
const value = options[key];
memo +=
value instanceof Date
? `; ${key}=${value.toUTCString()}`
: typeof value === "boolean"
? `; ${key}`
: `; ${key}=${value}`;
}
return memo;
import {
cookieStorage,
createCookieStorage,
createCookieStorageSignal
} from "./chunk-INHFJDUZ.js";
import "./chunk-V53AARZS.js";
import "./chunk-UHHZE4FR.js";
import "./chunk-JUWXSDKJ.js";
export {
cookieStorage,
createCookieStorage,
createCookieStorageSignal
};
/**
* handle cookies exactly like you would handle localStorage
*
* the main change is that setItem accepts the following options:
* ```typescript
* export type CookieOptions = {
* domain?: string;
* expires?: Date | number | String;
* path?: string;
* secure?: boolean;
* httpOnly?: boolean;
* maxAge?: number;
* sameSite?: "None" | "Lax" | "Strict";
* };
* ```
*/
export const cookieStorage = addClearMethod({
_cookies: [globalThis.document, "cookie"],
getItem: (key) => cookieStorage._cookies[0][cookieStorage._cookies[1]]
.match("(^|;)\\s*" + key + "\\s*=\\s*([^;]+)")
?.pop() ?? null,
setItem: (key, value, options) => {
cookieStorage._cookies[0][cookieStorage._cookies[1]] = `${key}=${value}${serializeCookieOptions(options)}`;
},
removeItem: (key) => {
cookieStorage._cookies[0][cookieStorage._cookies[1]] = `${key}=deleted${serializeCookieOptions({
expires: new Date(0)
})}`;
},
key: (index) => {
let key = null;
let count = 0;
cookieStorage._cookies[0][cookieStorage._cookies[1]].replace(/(?:^|;)\s*(.+?)\s*=\s*[^;]+/g, (_, found) => {
if (!key && found && count++ === index) {
key = found;
}
return "";
});
return key;
},
get length() {
let length = 0;
cookieStorage._cookies[0][cookieStorage._cookies[1]].replace(/(?:^|;)\s*.+?\s*=\s*[^;]+/g, (found) => {
length += found ? 1 : 0;
return "";
});
return length;
}
});
/**
* creates a reactive store but bound to document.cookie
*/
export const createCookieStorage = (props) => createStorage({ ...props, api: cookieStorage });
/**
* creates a reactive signal, but bound to document.cookie
*/
export const createCookieStorageSignal = (key, initialValue, props) => createStorageSignal(key, initialValue, { ...props, api: cookieStorage });

@@ -1,4 +0,25 @@

import { createStorage, createAsyncStorage, createStorageSignal, createLocalStorage, createSessionStorage } from "./storage";
import { cookieStorage, createCookieStorage } from "./cookies";
import { addClearMethod } from "./tools";
export { createStorage, createAsyncStorage, createStorageSignal, createLocalStorage, createCookieStorage, createSessionStorage, cookieStorage, addClearMethod };
import {
cookieStorage,
createCookieStorage
} from "./chunk-INHFJDUZ.js";
import {
createAsyncStorage,
createLocalStorage,
createSessionStorage,
createStorage,
createStorageSignal
} from "./chunk-V53AARZS.js";
import {
addClearMethod
} from "./chunk-UHHZE4FR.js";
import "./chunk-JUWXSDKJ.js";
export {
addClearMethod,
cookieStorage,
createAsyncStorage,
createCookieStorage,
createLocalStorage,
createSessionStorage,
createStorage,
createStorageSignal
};

@@ -1,224 +0,15 @@

import { createEffect, createSignal } from "solid-js";
export function createStorage(props) {
const apis = props?.api
? Array.isArray(props.api)
? props.api
: [props.api]
: [globalThis.localStorage].filter(Boolean);
const prefix = props?.prefix ? `${props.prefix}.` : "";
const signals = new Map();
const store = new Proxy({}, {
get(_, key) {
let node = signals.get(key);
if (!node) {
node = createSignal(undefined, { equals: false });
signals.set(key, node);
}
node[0]();
const value = apis.reduce((result, api) => {
if (result !== null || !api) {
return result;
}
return api.getItem(`${prefix}${key}`);
}, null);
if (value !== null && props?.deserializer) {
return props.deserializer(value, key, props?.options);
}
return value;
}
});
const setter = (key, value, options) => {
const filteredValue = props?.serializer
? props.serializer(value, key, options ?? props?.options)
: value;
apis.forEach(api => api.setItem(`${prefix}${key}`, filteredValue));
const node = signals.get(key);
node && node[1]();
};
const remove = (key) => apis.forEach(api => api.removeItem(key));
const clear = () => apis.forEach(api => api?.clear?.());
const toJSON = () => {
const result = {};
const addValue = (key, value) => {
if (!result.hasOwnProperty(key)) {
const filteredValue = value && props?.deserializer
? props.deserializer(value, key, props?.options)
: value;
if (filteredValue) {
result[key] = filteredValue;
}
}
};
apis.forEach(api => {
if (typeof api.getAll === "function") {
const values = api.getAll();
for (const key of values) {
addValue(key, values[key]);
}
}
else {
let index = 0, key;
while ((key = api.key(index++))) {
if (!result.hasOwnProperty(key)) {
addValue(key, api.getItem(key));
}
}
}
});
return result;
};
return [
store,
setter,
{
clear,
remove,
toJSON
}
];
}
export function createAsyncStorage(props) {
const apis = props?.api ? (Array.isArray(props.api) ? props.api : [props.api]) : [];
const prefix = props?.prefix ? `${props.prefix}.` : "";
const signals = new Map();
const store = new Proxy({}, {
get(_, key) {
let node = signals.get(key);
if (!node) {
node = createSignal(undefined, { equals: false });
signals.set(key, node);
}
node[0]();
return apis.reduce((result, api) => {
if (result !== null || !api) {
return result;
}
const value = api.getItem(`${prefix}${key}`);
if (value instanceof Promise) {
return value.then((value) => value && props?.deserializer ? props.deserializer(value, key, props?.options) : value);
}
return value !== null && props?.deserializer
? Promise.resolve(props.deserializer(value, key, props?.options))
: Promise.resolve(value);
}, null);
}
});
const setter = (key, value, options) => {
const filteredValue = props?.serializer
? props.serializer(value, key, options ?? props?.options)
: value;
return Promise.all(apis.map(api => api.setItem(`${prefix}${key}`, filteredValue, options ?? props?.options))).then(() => {
const node = signals.get(key);
node && node[1]();
});
};
const remove = (key) => Promise.all(apis.map(api => api.removeItem(`${prefix}${key}`))).then(() => {
const node = signals.get(key);
node && node[1]();
});
const clear = () => Promise.all(apis.map(async (api) => {
let index = 0, key;
while ((key = await api.key(index++))) {
await api.removeItem(key);
}
})).then(() => {
return;
});
const toJSON = async () => {
const result = {};
const addValue = (key, value) => {
if (!result.hasOwnProperty(key)) {
const filteredValue = value && props?.deserializer
? props.deserializer(value, key, props?.options)
: value;
if (filteredValue) {
result[key] = filteredValue;
}
}
};
await Promise.all(apis.map(async (api) => {
if (typeof api.getAll === "function") {
const values = await api.getAll();
for (const key of values) {
addValue(key, values[key]);
}
}
else {
let index = 0, key;
while ((key = await api.key(index++))) {
addValue(key, await api.getItem(key));
}
}
}));
return result;
};
return [
store,
setter,
{
remove,
clear,
toJSON
}
];
}
/**
* like createSignal, but bound to a localStorage-like API
* ```typescript
* type StorageWithOptions<O> = Storage; // but with options added to setItem
* type StorageProps<T extends string, O> = {
* api?: Storage | StorageWithOptions;
* // or an array thereof, default will be localStorage
* deserializer?: (value: string, key: string, options?: O) => T;
* serializer?: (value: T, key: string, options?: O) => string;
* options?: O; // options
* prefix?: string // will be prefixed to the key
* };
* createStorage<T extends string>(key: string, props?: StorageProps<T>) => [
* accessor: Accessor<T>, // basically like `value()`
* setter: Setter<T>, // like `setValue()`
* refetch: () => void // reloads from storage
* ]
* ```
*/
export function createStorageSignal(key, initialValue, props) {
const apis = props?.api
? Array.isArray(props.api)
? props.api
: [props.api]
: [globalThis.localStorage].filter(Boolean);
const prefix = props?.prefix ? `${props.prefix}.` : "";
const read = () => apis.reduce((result, api) => {
if (result !== null || !api) {
return result;
}
const value = api.getItem(`${prefix}${key}`);
if (value !== null && props?.deserializer) {
return props.deserializer(value, key, props?.options);
}
return value;
}, null);
const [accessor, setter] = createSignal(read() ?? initialValue);
createEffect(() => {
const value = accessor();
const filteredValue = props?.serializer
? props.serializer(value, key, props?.options)
: value;
if (value === null) {
apis.forEach(api => api.removeItem(`${prefix}${key}`));
}
else {
apis.forEach(api => api.setItem(`${prefix}${key}`, filteredValue, props?.options));
}
});
return [
accessor,
setter,
() => {
const value = read();
setter(value);
}
];
}
export const createLocalStorage = createStorage;
export const createSessionStorage = (props) => createStorage({ ...props, api: globalThis.sessionStorage });
import {
createAsyncStorage,
createLocalStorage,
createSessionStorage,
createStorage,
createStorageSignal
} from "./chunk-V53AARZS.js";
import "./chunk-JUWXSDKJ.js";
export {
createAsyncStorage,
createLocalStorage,
createSessionStorage,
createStorage,
createStorageSignal
};

@@ -1,15 +0,7 @@

/**
* adds a `.clear` method to a Storage without one only using `.key`/`.removeItem`
*/
export const addClearMethod = (storage) => {
if (typeof storage.clear === "function") {
return storage;
}
storage.clear = () => {
let key;
while ((key = storage.key(0))) {
storage.removeItem(key);
}
};
return storage;
import {
addClearMethod
} from "./chunk-UHHZE4FR.js";
import "./chunk-JUWXSDKJ.js";
export {
addClearMethod
};

@@ -1,2 +0,2 @@

export declare type StorageWithOptions<O> = {
declare type StorageWithOptions<O> = {
clear: () => void;

@@ -13,5 +13,5 @@ getItem: (key: string, options?: O) => string | null;

};
export declare type StorageDeserializer<T, O> = (value: string, key: string, options?: O) => T;
export declare type StorageSerializer<T, O> = (value: T, key: string, options?: O) => string;
export declare type StringStorageProps<A, O, T = string> = {
declare type StorageDeserializer<T, O> = (value: string, key: string, options?: O) => T;
declare type StorageSerializer<T, O> = (value: T, key: string, options?: O) => string;
declare type StringStorageProps<A, O, T = string> = {
api?: A | A[];

@@ -23,3 +23,3 @@ deserializer?: StorageDeserializer<T, O>;

};
export declare type AnyStorageProps<A, O, T> = {
declare type AnyStorageProps<A, O, T> = {
api?: A | A[];

@@ -31,6 +31,6 @@ deserializer: StorageDeserializer<T, O>;

};
export declare type StorageProps<T, A, O> = T extends string ? StringStorageProps<A, O> : AnyStorageProps<A, O, T>;
export declare type StorageObject<T> = Record<string, T>;
export declare type StorageSetter<T, O> = (key: string, value: T, options?: O) => void;
export declare type StorageActions<T> = {
declare type StorageProps<T, A, O> = T extends string ? StringStorageProps<A, O> : AnyStorageProps<A, O, T>;
declare type StorageObject<T> = Record<string, T>;
declare type StorageSetter<T, O> = (key: string, value: T, options?: O) => void;
declare type StorageActions<T> = {
remove: (key: string) => void;

@@ -42,3 +42,3 @@ clear: () => void;

};
export declare type AsyncStorage = {
declare type AsyncStorage = {
clear?: () => Promise<void> | void;

@@ -53,3 +53,3 @@ getItem: (key: string) => Promise<string | null> | string | null;

};
export declare type AsyncStorageWithOptions<O> = {
declare type AsyncStorageWithOptions<O> = {
clear?: () => Promise<void> | void;

@@ -64,5 +64,5 @@ getItem: (key: string, options?: O) => Promise<string | null> | string | null;

};
export declare type AsyncStorageObject<T> = Record<string, Promise<T | null>>;
export declare type AsyncStorageSetter<T, O> = (key: string, value: T, options?: O) => Promise<void> | void;
export declare type AsyncStorageActions<T> = {
declare type AsyncStorageObject<T> = Record<string, Promise<T | null>>;
declare type AsyncStorageSetter<T, O> = (key: string, value: T, options?: O) => Promise<void> | void;
declare type AsyncStorageActions<T> = {
remove: (key: string) => Promise<void> | void;

@@ -74,3 +74,3 @@ clear: () => Promise<void> | void;

};
export declare type StorageSignalProps<T, A, O> = StorageProps<T, A, O> & {
declare type StorageSignalProps<T, A, O> = StorageProps<T, A, O> & {
equals?: false | ((prev: T, next: T) => boolean) | undefined;

@@ -80,1 +80,3 @@ name?: string | undefined;

};
export { AnyStorageProps, AsyncStorage, AsyncStorageActions, AsyncStorageObject, AsyncStorageSetter, AsyncStorageWithOptions, StorageActions, StorageDeserializer, StorageObject, StorageProps, StorageSerializer, StorageSetter, StorageSignalProps, StorageWithOptions, StringStorageProps };
{
"name": "@solid-primitives/storage",
"version": "1.0.4",
"version": "1.0.7",
"description": "Primitive that provides reactive wrappers for storage access",

@@ -8,20 +8,30 @@ "author": "Alex Lohr <alex.lohr@logmein.com>",

"homepage": "https://github.com/davedbase/solid-primitives/tree/main/packages/storage",
"private": false,
"main": "dist/cjs/index.cjs",
"module": "dist/index.js",
"types": "dist/index.d.ts",
"type": "module",
"repository": {
"type": "git",
"url": "git+https://github.com/davedbase/solid-primitives.git"
},
"primitive": {
"name": "storage",
"stage": 3,
"list": [
"createStorage",
"createCookieStorage",
"createAsyncStorage",
"createStorageSignal",
"createLocalStorage",
"createSessionStorage"
],
"category": "Browser APIs"
},
"files": [
"dist"
],
"exports": {
"require": "./dist/cjs/index.cjs",
"import": "./dist/index.js",
"default": "./dist/index.js"
},
"sideEffects": "false",
"private": false,
"sideEffects": false,
"type": "module",
"main": "./dist/index.cjs",
"module": "./dist/index.js",
"types": "./dist/index.d.ts",
"scripts": {
"prebuild": "npm run clean",
"clean": "rimraf dist/",
"build": "tsc && tsc --target es5 --module commonjs --declaration false --outDir ./dist/cjs",
"build": "tsup",
"test": "uvu -r solid-register"

@@ -40,6 +50,7 @@ },

"solid-register": "^0.0.18",
"tsup": "^5.10.1",
"typescript": "^4.5.2",
"uvu": "^0.5.2"
},
"dependencies": {
"peerDependencies": {
"solid-js": "^1.2.5"

@@ -46,0 +57,0 @@ },

@@ -1,9 +0,1 @@

---
Name: storage
Stage: 3
Package: "@solid-primitives/storage"
Primitives: createStorage, createCookieStorage, createAsyncStorage, createStorageSignal, createLocalStorage, createSessionStorage
Category: Browser APIs
---
# @solid-primitives/storage

@@ -17,4 +9,14 @@

## Installation
```
npm install @solid-primitives/storage
# or
yarn add @solid-primitives/storage
```
## How to use it
### Basic Usage
`createStorage` is meant to wrap any localStorage-like API to be as accessible as a [Solid Store](https://www.solidjs.com/docs/latest/api#createstore). The main differences are

@@ -167,3 +169,3 @@

1.0.4
1.0.7

@@ -170,0 +172,0 @@ Patch CJS support.

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc