Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/kwangure/storables
Useful reactive Svelte stores
https://github.com/kwangure/storables
forms localstorage readable svelte sveltejs validation writable
Last synced: 17 days ago
JSON representation
Useful reactive Svelte stores
- Host: GitHub
- URL: https://github.com/kwangure/storables
- Owner: kwangure
- Created: 2021-08-02T15:06:49.000Z (over 3 years ago)
- Default Branch: master
- Last Pushed: 2021-12-17T03:22:39.000Z (about 3 years ago)
- Last Synced: 2024-12-01T12:24:18.893Z (3 months ago)
- Topics: forms, localstorage, readable, svelte, sveltejs, validation, writable
- Language: TypeScript
- Homepage:
- Size: 1.06 MB
- Stars: 0
- Watchers: 2
- Forks: 0
- Open Issues: 2
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
Awesome Lists containing this project
README
# storables
Svelte's built-in stores are not always ergonomic when you have to mix them
with imperative code. Storables remedy this by letting you to embed logic
within a store's lifetime.## checkable
`checkable` works like Svelte's `writable` but with built-in asynchronous validation.### Features
-
β Asynchronous validation```javascript
const initialValue = "John Smith";
const { username, usernameCheckStatus } = checkable({
name: "username",
async check(newUsername) {
// This value is invalid, but I know what I'm doing.
if (userIsTyping) return false;
// This value is invalid, scream!
if (await alreadyExists(newUsername)) {
throw Error("Username already taken");
}
// This value is valid
return true;
},
}, initialValue);
````$usernameCheckStatus` is `"pending"` while validating the value asynchronously.
`$usernameCheckStatus` is `"done"` when validation is complete.
`$usernameCheckStatus` is `"error"` if the validation throws an error.
In the above example, `usernameCheckStatus.error` is `Error("Username is already taken")` if
`$usernameCheckStatus === "error"`. It is `null` otherwise.Unlike the transformable's `assert`, `check` is not write-blocking.
The default/initial value is not validated.
## persistable
Persist your store's value in localStorage or your database βstore it anywhere.### Features
-
πΎ Asynchronous storage```javascript
const defaultValue = 0;
const { count } = persistable({
name: "count",
io: {
read({ set }) {
readFromDatabase()
.then(value => set(value))
.catch(() => defaultValue);
const cleanUp = onDatabaseChange(value => set(value));
return cleanUp;
},
write: (value, { set, error }) => {
try {
writeToDatabase(value).then(value => set(value););
} catch (e) {
error("Save unsuccessful. Please try again later.");
}
},
},
});
```-
β Validation```javascript
const { count, countWriteStatus } = persistable({
name: "count",
io: {
read: ({ set }) => {
set(JSON.parse(localStorage.getItem("count")));
},
write: (value, { set, error }) => {
if (isInvalid(value)) {
error("Heeyo! Value is invalid.");
}
localStorage.setItem("count", JSON.stringify(value));
set(value);
},
},
});
````$countWriteStatus` is `"pending"` while writing value.
`$countWriteStatus` is `"done"` when writing is complete.
`$countWriteStatus` is `"error"` if the `write` throws an error.
In the above example, `countWriteStatus.error` is `Error("Could not write invalid value")`
if `$countWriteStatus === "error"`. It is `null` otherwise.
## transformable
If Svelte's built-in `writable` and `derived` stores had a baby, it would be `transformable`.
### Features
-
π Two-way transforms (...more like many-way transforms)```javascript
const { dateObject, number } = transformable({
name: "number",
transforms: {
dateObject: {
to: (date) => date.getTime(),
from: (number) => new Date(number),
},
},
}, new Date().getTime());
```Updating `number` will call its own subscribers with `$number` and subscribers
of `dateObject` with `new Date($number)`. Updating `dateObject` will call its own
subscribers with `$dateObject` and subscribers of `number` with `$dateObject.getTime()`.This is handy if, for example, you want to display minutes to a user but your code
thinks in milliseconds.-
β Validation```javascript
const now = new Date().getTime()
const { number, numberAssertStatus } = transformable({
name: "number",
assert(number) {
// This is an invalid value, but I know what I'm doing.
if (number === undefined) return false;
// This is an error, scream!
if (number < now) throw Error("Date must be after now");
// This is a valid number
return true;
}
}, now);
````numberAssertStatus.error` is `Error("Date must be after now")` if
`$numberAssertStatus === "error"`. It is `null` otherwise.`assert` is write-blocking. If it throws or returns `false` the value of the store
will not change and subscribers will not be called.The default/initial value is not validated.