Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions packages/docs/.vitepress/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -368,10 +368,10 @@ function getUtilsSidebar() {
collapsed: true,
items: [
{ text: 'createStorage', link: '/utils/storage/createStorage.html' },
{ text: 'useLocalStorage', link: '/utils/storage/useLocalStorage.html' },
{ text: 'useSessionStorage', link: '/utils/storage/useSessionStorage.html' },
{ text: 'useUrlSearchParams', link: '/utils/storage/useUrlSearchParams.html' },
{ text: 'useUrlSearchParamsInHash', link: '/utils/storage/useUrlSearchParamsInHash.html' },
{ text: 'createLocalStorage', link: '/utils/storage/createLocalStorage.html' },
{ text: 'createSessionStorage', link: '/utils/storage/createSessionStorage.html' },
{ text: 'createUrlSearchParamsStorage', link: '/utils/storage/createUrlSearchParamsStorage.html' },
{ text: 'createUrlSearchParamsInHashStorage', link: '/utils/storage/createUrlSearchParamsInHashStorage.html' },
{ text: 'Providers', link: '/utils/storage/providers.html' },
],
},
Expand Down
12 changes: 8 additions & 4 deletions packages/docs/api/html/data-component.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,10 +51,14 @@ The previous HTML example can be rewritten to:
<title>App</title>
</head>
<body>
<div data-component="Component"></div> // [!code --]
<div data-component="CustomName"></div> // [!code --]
<tk-component></tk-component> // [!code ++]
<tk-custom-name></tk-custom-name> // [!code ++]
<div data-component="Component"></div>
// [!code --]
<div data-component="CustomName"></div>
// [!code --]
<tk-component></tk-component>
// [!code ++]
<tk-custom-name></tk-custom-name>
// [!code ++]
</body>
</html>
```
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
# useLocalStorage
# createLocalStorage

Create a storage instance backed by `localStorage`. Values persist across page reloads and are synced across tabs via the `storage` event.
Create a storage instance backed by `globalThis.localStorage`. The underlying storage is resolved lazily from `globalThis` when the instance is used, so it can be imported before a browser-like global exists. Values persist across page reloads and are synced across tabs via the `storage` event when available.

## Usage

```js twoslash
// @twoslash-cache: {"v":1,"hash":"088a272689b725269922c7afba5cb8bac42148bc848708f323c0939c2712e2d5","data":"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="}
import { useLocalStorage } from '@studiometa/js-toolkit/utils';
import { createLocalStorage } from '@studiometa/js-toolkit/utils';

const storage = useLocalStorage({ prefix: 'myapp:' });
const storage = createLocalStorage({ prefix: 'myapp:' });

storage.set('theme', 'dark');
storage.get('theme'); // 'dark'
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
# useSessionStorage
# createSessionStorage

Create a storage instance backed by `sessionStorage`. Values persist for the duration of the page session.
Create a storage instance backed by `globalThis.sessionStorage`. The underlying storage is resolved lazily from `globalThis` when the instance is used, so it can be imported before a browser-like global exists. Values persist for the duration of the page session when available.

## Usage

```js twoslash
// @twoslash-cache: {"v":1,"hash":"69de48acfe7afd1f4722f2125a3205977466917296023382c3b39c4daafd620b","data":"N4Igdg9gJgpgziAXAbVAFwJ4AcZJACwgDcYAnEAGhDRgA808AKAQwBsBLZuASgAIAzAK5gAxmnYQwvQXBgBleHAlg5aCKWYBzGAB4AKrzo0wUOLwBKMEeqg64aUuzCaKvZmAwA+XgF4LVmzsHJxc3D09PRggscUk4AH5EXgB5AFt2NB1VdS0YZJjlOH1PVwAdECxSYnZYUnLPbiTsjW0ASTB7dxFdPU9SsHZUrHU0aVkFOCVJZtzKECgIEQREEABhUhhmGjdeWUnlGe1pcQ5MADo5tC1l5GQK5g1UuejYjt5DmF4Xwt5GSph+OxaK5ZI42OwAF5kbgXAC6FDuGzQglIHUoYEErFYsPhIE6pAYiAAnFRWDBnGh8EgAIwAdioV1I2kJIBk8kUBzULVwpKcuEQAAYqCJ8A9mGIyEgiQBfCjobD8gjESUMox4awdUb2HLaJpc3LtTqiXSWaykWz2RzOVzuLyeOb4wm0gDMpPJmkpSHp1AezLw2u5cw4YH5ACZhaKNBLyIgAGyy+U4PCEEjkVX0Jjgrh8NkTKYqfXaHSmwKWkI28KRb5xRIpdKZD75V5FEvmoJW0K2iJlCpVIg1Mj1XgAH2kJgBfKgjXehZghquxuLATbZetYTt/UGwwJY3Z+2ms7mCyWeHWm22zF2HIPOs+ghOGQwFwZ1yQt3uj2eBTiM9vX2/bx/BsgLAleYIcFCpAwiA8KIjAyKoggFAYliOJUI6SAAByuiAZIUlSiB0i+TLwXgubXgWt5BnySDhiAIpitGNLxnK1AKsmypptQaorEB0RkJgfD/CBtarpoI5jrAgIhlAR6LMsIAANIwBgvDCUCAjqLwYDMKk8BYOKIRnLwACCWK8AA1ipZgAO7sOZABGnzqbQMBQLwdmUrwlLsGYYnPj6mg3HcdC6VgZJzAA5KkGDMFgWCIJFHn2awuxcp8VmqZFlIwHpSVcLw0WxfFiA5XlMG4hhhECjheEegRsbEX6KwudRIa0RGjE0DGzosYmiopiq3EZisGr2Glt56re85dCay4WsEa5dva6GMoS1Kht6dWeog3qMs1eKHry7WIAALJ1UbdUgAoJmxSYrINXE0CNICMHplLQHwHwzYurYLR2FZ2mcsiZOUahWWA9SMJlSRgxAEPlK4RBsIIMBJLa05EBANQOmtNLOgArG6+FIDh+2kSsINtfy530ZG4pXYgmG3Zg91Kqmlw8fRcRarOU3cj93RLma/3luuES4w860EySuHujte2+hTh1Ucd/JE3TXWSoKLPsQ9nGcy9b3wYQU6/gLmqzcLpaLZ2lbA/BOjlHQWDsBscBQzDvDO7Qrvu4jvDI6wqPox4mPY7Jq1S8xW3ywRZNKyyVNq0gGsMZd2vM6xrMDQb6YsmNvOTebBqW7983tmLy2SwSNJEkKcsk7tTXKwGswp83msZzGN3Z3r7NDc9LLGx9ZvfWXQt/ZXS328yTvUPD5KeypsMLwjIDTravwANTUl8qasBAzBTjX61EphxP1aTLcsn6HfeunDOZ9KuLWLAeBbiMvDALueacn+0oBBVFSIVAAAvYQQUAJDvWYAAegAFZwAALRqAgKwCyGRYH3nsnASKABufo/RC4TW5L4X+FEPiMB/i5JIkU9j5kSrwaU3ACGQ01LeB2aBGDZUXmASKrhIrMAciIDazpIosP6G3bQnDuEuzdvAfhvBeoCgFBIthUiYBnGZNw8G5JxF4N4LA2BhUhEiNDGIuYMCkCgCMOSfMeBEEgGlNKIAA==="}
import { useSessionStorage } from '@studiometa/js-toolkit/utils';
import { createSessionStorage } from '@studiometa/js-toolkit/utils';

const storage = useSessionStorage({ prefix: 'session:' });
const storage = createSessionStorage({ prefix: 'session:' });

storage.set('token', 'abc123');
storage.set('expires', 3600);
Expand Down
16 changes: 11 additions & 5 deletions packages/docs/utils/storage/createStorage.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,8 @@ const storage = createStorage<AppStorage>();
storage.set('theme', 'dark'); // βœ… typed
// @errors: 2345
storage.set('theme', 'blue'); // ❌ type error
storage.get('user'); // { name: string; id: number } | null
storage.get('user'); // { name: string; id: number } | undefined
storage.delete('user');
```

## Parameters
Expand All @@ -66,11 +67,16 @@ storage.get('user'); // { name: string; id: number } | null

A `StorageInstance<T>` with the following methods:

- **`get(key)`** β€” Get the value for a key. Returns `null` if not set.
- **`get(key)`** β€” Get the value for a key. Returns `undefined` if not set or if the stored value is corrupted.
- **`get(key, defaultValue)`** β€” Get the value for a key, returning `defaultValue` if not set.
- **`set(key, value)`** β€” Set a value. Pass `null` to remove the key.
- **`set(key, value)`** β€” Set a value. `null` is stored as a real value when your type allows it.
- **`delete(key)`** β€” Remove a key from storage. Subscribers are notified with `undefined`.
- **`has(key)`** β€” Check if a key exists in storage.
- **`keys()`** β€” List all keys managed by this instance. When a `prefix` is set, only prefixed keys are returned (with the prefix stripped).
- **`clear()`** β€” Remove all entries. When a `prefix` is set, only prefixed keys are cleared β€” other keys in the same provider are left untouched.
- **`subscribe(key, callback)`** β€” Subscribe to changes on a key. Returns an unsubscribe function. Listeners are notified on both local changes and external sync events (cross-tab, navigation).
- **`clear()`** β€” Remove all entries. When a `prefix` is set, only prefixed keys are cleared β€” other keys in the same provider are left untouched. Subscribers are notified with `undefined`.
- **`subscribe(key, callback)`** β€” Subscribe to changes on a key. Returns an unsubscribe function. Listeners are notified on both local changes and external sync events (cross-tab, navigation). `undefined` means the key is absent.
- **`destroy()`** β€” Clean up all listeners and event handlers.

::: warning Cleanup
Each `createStorage()` call registers a global event listener (when the provider has a `syncEvent`). Always call `destroy()` when the storage instance is no longer needed to avoid memory leaks β€” for example in a component's unmount/destroy lifecycle hook.
:::
Original file line number Diff line number Diff line change
@@ -1,16 +1,18 @@
# useUrlSearchParamsInHash
# createUrlSearchParamsInHashStorage

Create a storage instance backed by URL hash params (`#key=value`). Useful for client-side state that shouldn't be sent to the server, like tab selection or UI mode.

This storage is browser-only: it requires `window.location` and `window.history`. The browser context is checked when the provider is created. In non-browser environments, it falls back to a no-op provider.

By default, changes use `replaceState` to avoid polluting browser history. Use `{ push: true }` to create history entries instead.

## Usage

```js twoslash
// @twoslash-cache: {"v":1,"hash":"56dfa762cb1028d977df774e7d67ad47b9337903c79572f2f5b49c1316f4f379","data":"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"}
import { useUrlSearchParamsInHash } from '@studiometa/js-toolkit/utils';
import { createUrlSearchParamsInHashStorage } from '@studiometa/js-toolkit/utils';

const storage = useUrlSearchParamsInHash();
const storage = createUrlSearchParamsInHashStorage();

// URL: /page
storage.set('tab', 'settings');
Expand All @@ -27,6 +29,10 @@ storage.subscribe('tab', (value) => {
});
```

::: tip Values are JSON-serialized
All values are serialized with `JSON.stringify` before being written to the URL hash. This means string values will include quotes (e.g. `#tab=%22settings%22`). Use a custom `serializer` if you prefer raw strings.
:::

## Parameters

- `options` (`StorageOptions & UrlProviderOptions`): Optional configuration.
Expand Down
Loading
Loading