All Projects → PixievoltNo1 → svelte-writable-derived

PixievoltNo1 / svelte-writable-derived

Licence: MIT license
Two-way data-transforming stores for Svelte

Programming Languages

javascript
184084 projects - #8 most used programming language

Projects that are alternatives of or similar to svelte-writable-derived

svelte-starter-kit
Svelte with brilliant bells and useful whistles
Stars: ✭ 384 (+490.77%)
Mutual labels:  svelte, svelte3
svelte-form
JSON Schema form for Svelte v3
Stars: ✭ 47 (-27.69%)
Mutual labels:  svelte, svelte3
svelte-meteor-data
Reactively track Meteor data inside Svelte components
Stars: ✭ 14 (-78.46%)
Mutual labels:  svelte, svelte3
s-date-range-picker
📅 A date range picker built with Svelte
Stars: ✭ 13 (-80%)
Mutual labels:  svelte, svelte3
BeatHub
Small, simple, and fast custom beatmap browser & downloader built with Svelte
Stars: ✭ 13 (-80%)
Mutual labels:  svelte, svelte3
svelte-accessible-dialog
An accessible dialog component for Svelte apps
Stars: ✭ 24 (-63.08%)
Mutual labels:  svelte, svelte3
svelte-spinkit
A collection of loading indicators animated with CSS for Svelte
Stars: ✭ 27 (-58.46%)
Mutual labels:  svelte, svelte3
svelte-headlessui
Unofficial Svelte port of Headless UI components
Stars: ✭ 564 (+767.69%)
Mutual labels:  svelte, svelte3
svelte-portal
Svelte component for rendering outside the DOM of parent component
Stars: ✭ 261 (+301.54%)
Mutual labels:  svelte, svelte3
svelte-interview-questions
Concepts and Questions related to Svelte - Part of official Svelte resources list
Stars: ✭ 18 (-72.31%)
Mutual labels:  svelte, svelte3
svelte-loader-hot
Webpack loader for svelte components with HMR support
Stars: ✭ 22 (-66.15%)
Mutual labels:  svelte, svelte3
Svelte Material Ui
Svelte Material UI Components
Stars: ✭ 2,081 (+3101.54%)
Mutual labels:  svelte, svelte3
perfect-home
firefox newtab/home replacement
Stars: ✭ 101 (+55.38%)
Mutual labels:  svelte, svelte3
mmss-client
No description or website provided.
Stars: ✭ 16 (-75.38%)
Mutual labels:  svelte, svelte3
svelte-webcomponents
A ready-to-use project template to build custom elements (web components) with Svelte 3 with support and examples for web components, jest, sass, nested components with props, eslinting, stylelinting, Github actions, propagating custom events from shadow-DOM to real-DOM etc.
Stars: ✭ 22 (-66.15%)
Mutual labels:  svelte, svelte3
ui-svelte
A component library for Svelte
Stars: ✭ 18 (-72.31%)
Mutual labels:  svelte, svelte3
svelte-inview
A Svelte action that monitors an element enters or leaves the viewport.🔥
Stars: ✭ 358 (+450.77%)
Mutual labels:  svelte, svelte3
spellbook
Spellbook is a bookmark extension for Chrome and Firefox
Stars: ✭ 19 (-70.77%)
Mutual labels:  svelte
svelte-datagrid
Svelte data grid spreadsheet best best features and performance from excel
Stars: ✭ 48 (-26.15%)
Mutual labels:  svelte
SvelteTetris
Basic Tetris game created with Svelte
Stars: ✭ 21 (-67.69%)
Mutual labels:  svelte

svelte-writable-derived

npm Bundle size License GitHub Repo stars

For users of Svelte v3, this is a read-write variant of Svelte's derived stores that accepts an extra callback to send values back to the source. It builds on the derived & writable stores provided by Svelte, and emulates their behavior as closely as possible.

This project has a Code of Conduct. By participating in the Git repo or issues tracker, you agree to be as courteous, welcoming, and generally a lovely person as its terms require. 😊

Default & named export: writableDerived()

Parameters: origins (store or array of stores), derive (function), reflect (see documentation), optional initial (any)
Returns a store with writable methods

Create a store that behaves similarly to Svelte's derived, with origins, derive, and initial working like its 1st, 2nd, and 3rd parameters respectively. Values introduced to the store via its set and update methods are passed to the new 3rd parameter, reflect, which can in turn set values for the origin stores.

It is not possible for derived and reflect to trigger calls to each other, provided they only use the set callbacks provided to them and do not reach out to any outer set or update.

New parameter: reflect

One of the following:

  • Function with parameters: reflecting (any), optional set (function)
  • Object with property withOld containing function with parameters: reflecting (any), old (any), optional set (function)

The provided function is called when the derived store gets a new value via its set and update methods (not via the derive callback). Its reflecting parameter is this new value. The set parameter accepts a value to set in the origin store, if origins was a store, or an array of values to set if origins was an array. If the set parameter receives an array that's sparse or shorter than origins, it will only set the stores it has elements for, and other stores don't necessarily need to be writable. If the function doesn't take a set parameter, its return value will be used to set origin stores just as if it were passed to set.

reflect is called after the derived store's subscriptions are called. If the derived store has its set and/or update methods called again in the process of calling its subscriptions, reflect will be called only once, with the most-recently-set value.

If reflect takes a set parameter, it may return a cleanup function that will be called immediately before the next reflect call. (Unlike its derive counterpart, reflect's cleanup function is never called in response to unsubscriptions.)

If the reflect parameter is provided a function via an object with a withOld property, that function will be called with an additional old parameter after reflecting. This is the initial value of the origin stores, and will be an array if origins was an array.

Named export: propertyStore()

Parameters: origin (store), propName (string, number, symbol, or array of strings/numbers/symbols)
Returns a store with writable methods

A utility wrapper for writableDerived. Given a store containing an object, this function returns a store containing the value of the object's property propName. If propName is an array, it's used as a path to navigate nested objects.

Regarding Subscription-less svelte-writable-derived Stores

One of the ways this package emulates the behavior of Svelte's derived is that it does not subscribe to any origin store until the derived store itself has a subscription. However, there's an exception: Calling the set and update methods when the derived store has no subscriptions will subscribe to & then unsubscribe from all its origins.

Examples

Making an object store from a JSON string store

import { writable, get } from "svelte/store";
import writableDerived from "svelte-writable-derived";

var jsonStore = writable(`{"I'm a property": true}`);
var objectStore = writableDerived(
	jsonStore,
	(json) => JSON.parse(json),
	(object) => JSON.stringify(object)
);
console.log( Object.keys( get(objectStore) ) ); // ["I'm a property"]
objectStore.set({"I'm not a property": false});
console.log( get(jsonStore) ); // "{\"I'm not a property\": false}"

Making a single-value store from an object store

import { writable, get } from "svelte/store";
import { propertyStore } from "svelte-writable-derived";

var objectStore = writable({"a horse": "a horse", "of course": "of course"});
var valueStore = propertyStore(objectStore, "a horse");
console.log( get(valueStore) ); // "a horse"
valueStore.set("*whinny*");
console.log( get(objectStore) ); // {"a horse": "*whinny*", "of course": "of course"}

// propertyStore is just a wrapper. You could also use writableDerived directly:

import writableDerived from "svelte-writable-derived";

var valueStore = writableDerived(
	objectStore,
	(object) => object["a horse"],
	{ withOld(reflecting, object) {
		object["a horse"] = reflecting;
		return object; // needed to call objectStore.set with the proper value
	} }
);

... when the object is an array

// An array is an object with numerically-named properties.
// Access them using a number for the propName parameter.

import { writable, get } from "svelte/store";
import { propertyStore } from "svelte-writable-derived";

var treasureCoordinates = writable([7, -2, 31]);
var treasureElevation = propertyStore(treasureCoordinates, 1);
console.log( get(treasureElevation) ); // -2
treasureElevation.set(1); // dig up the treasure
console.log( get(treasureCoordinates) ); // [7, 1, 31]

... when the value is deeply nested in the object

import { writable, get } from "svelte/store";
import { propertyStore } from "svelte-writable-derived";

var objectStore = writable({ deeply: { buried: { item: "trash" } } });
var valueStore = propertyStore(objectStore, ["deeply", "buried", "item"]);
console.log( get(valueStore) ); // "trash"
valueStore.set("treasure");
console.log( get(objectStore) ); // { deeply: { buried: { item: "treasure" } } }

// Using writableDerived directly:

import writableDerived from "svelte-writable-derived";

var valueStore = writableDerived(
	objectStore,
	(object) => object.deeply.buried.item,
	{ withOld(reflecting, object) {
		object.deeply.buried.item = reflecting;
		return object; // needed to call objectStore.set with the proper value
	} }
);

Making an object store from several single-value stores

import { writable, get } from "svelte/store";
import writableDerived from "svelte-writable-derived";

var valueStore1 = "sparta", valueStore2 = "monty python's flying circus";
var objectStore = writableDerived(
	[valueStore1, valueStore2],
	([value1, value2]) => ( {"this is": value1, "it's": value2} ),
	(object) => [ object["this is"], object["it's"] ]
);
console.log( get(objectStore) ); // {"this is": "sparta", "it's": "monty python's flying circus"}
objectStore.set( {"this is": "rocket league", "it's": "over 9000"} );
console.log( get(valueStore1), get(valueStore2) ); // "rocket league" "over 9000"

Chaining all of the above together

// What if Rube Goldberg were a JavaScript developer?
import { writable, get } from "svelte/store";
import { writableDerived, propertyStore } from "svelte-writable-derived";

var jsonStore = writable(`{"owner": "dragon", "possessions": ["crown", "gold"]}`);
var hoardStore = writableDerived(
	jsonStore,
	(json) => JSON.parse(json),
	(object) => JSON.stringify(object)
);

var hoarderStore = propertyStore(hoardStore, "owner");
var hoardContentsStore = propertyStore(hoardStore, "possessions");

var itemListStore = writableDerived(
	[hoarderStore, hoardContentsStore],
	([hoarder, hoardContents]) => {
		return hoardContents.map( (item) => {
			return {item, owner: hoarder};
		});
	},
	(itemList) => {
		// This is only for demonstration purposes, so we won't handle differing owners
		var hoarder = itemList[0].owner;
		var hoardContents = itemList.map( (itemListEntry) => {
			return itemListEntry["item"];
		} );
		return [hoarder, hoardContents];
	}
);

jsonStore.subscribe(console.log);
hoardStore.subscribe(console.log);
hoarderStore.subscribe(console.log);
// skipping hoardContentsStore
itemListStore.subscribe(console.log);
itemListStore.update( (itemList) => {
	return itemList.map( (itemListEntry) => {
		return {item: itemListEntry.item, owner: "protagonist"};
	} );
} );
/*
	Upon the update, the console logs:
	[{item: "crown", owner: "protagonist"}, {item: "gold", owner: "protagonist"}]
	"protagonist"
	{owner: "protagonist", possessions: ["crown", "gold"]}
	"{\"owner\": \"protagonist\", \"possessions\": [\"crown\", \"gold\"]}"
*/

Browser compatibility

This package should run anywhere Svelte can run. Use transpilers/polyfills as needed.

💖 Support the developer

I muchly appreciate any way you'd like to show your thanks - knowing people are helped gives me warm fuzzies and makes it all worthwhile!

💸 ... with money

You can make a one-time donation or become an ongoing sponsor at my Sponsus page, and sponsors can ask me to prioritize development of this package.

💌 ... with kind words

Current contact info is on this page - or you can create an "issue" on this repo just to say thanks! Thank-you "issues" will be closed right away, but are treasured regardless~

🤝 ... with a job

Want me to sling some JavaScript for you? Look over my other work and contact me!

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].