typescript version of store

pull/2733/head
Sander Hahn 6 years ago
parent 438acdc09a
commit 3b4c6ed4eb

2
.gitignore vendored

@ -6,7 +6,7 @@ node_modules
/compiler.js
/index.js
/internal.*
/store.js
/store.*
/easing.js
/motion.*
/transition.js

@ -31,7 +31,8 @@
"dev": "rollup -cw",
"pretest": "npm run build",
"posttest": "agadoo src/internal/index.js",
"prepublishOnly": "export PUBLISH=true && npm run lint && npm test"
"prepublishOnly": "export PUBLISH=true && npm run lint && npm test",
"tsd": "tsc -d src/store.ts --outDir ."
},
"repository": {
"type": "git",

@ -87,8 +87,37 @@ export default [
external: id => id.startsWith('svelte/')
},
/* store.mjs */
{
input: `src/store.ts`,
output: [
{
file: `store.mjs`,
format: 'esm',
paths: id => id.startsWith('svelte/') && id.replace('svelte', '.')
},
{
file: `store.js`,
format: 'cjs',
paths: id => id.startsWith('svelte/') && id.replace('svelte', '.')
}
],
plugins: [
is_publish
? typescript({
include: 'src/**',
exclude: 'src/internal/**',
typescript: require('typescript')
})
: sucrase({
transforms: ['typescript']
})
],
external: id => id.startsWith('svelte/')
},
// everything else
...['index', 'store', 'easing', 'transition', 'animate'].map(name => ({
...['index', 'easing', 'transition', 'animate'].map(name => ({
input: `${name}.mjs`,
output: {
file: `${name}.js`,

@ -0,0 +1,130 @@
import { run_all, noop, safe_not_equal } from './internal/utils';
type Subscriber<T> = (value: T) => void;
type Unsubscriber = () => void;
type Updater<T> = (value: T) => T;
type Invalidater<T> = (value?: T) => void;
type StartStopNotifier<T> = (set: Subscriber<T>) => Unsubscriber | void;
export interface ReadableStore<T> {
subscribe(run: Subscriber<T>, invalidate?: Invalidater<T>): Unsubscriber;
}
export interface WritableStore<T> extends ReadableStore<T> {
set(value: T): void;
update(updater: Updater<T>): void;
}
type SubscribeInvalidateTuple<T> = [Subscriber<T>, Invalidater<T>];
export function readable<T>(value: T, start: StartStopNotifier<T>): ReadableStore<T> {
return {
subscribe: writable(value, start).subscribe,
};
}
export function writable<T>(value: T, start: StartStopNotifier<T> = noop): WritableStore<T> {
let stop: Unsubscriber;
const subscribers: Array<SubscribeInvalidateTuple<T>> = [];
function set(new_value: T): void {
if (safe_not_equal(value, new_value)) {
value = new_value;
if (!stop) {
return; // not ready
}
subscribers.forEach((s) => s[1]());
subscribers.forEach((s) => s[0](value));
}
}
function update(fn: Updater<T>): void {
set(fn(value));
}
function subscribe(run: Subscriber<T>, invalidate: Invalidater<T> = noop): Unsubscriber {
const subscriber: SubscribeInvalidateTuple<T> = [run, invalidate];
subscribers.push(subscriber);
if (subscribers.length === 1) {
stop = start(set) || noop;
}
run(value);
return () => {
const index = subscribers.indexOf(subscriber);
if (index !== -1) {
subscribers.splice(index, 1);
}
if (subscribers.length === 0) {
stop();
}
};
}
return { set, update, subscribe };
}
export function derived<T>(
stores: ReadableStore<T> | Array<ReadableStore<T>>,
fn: (values: T | T[], set?: Subscriber<T>) => T | Unsubscriber | void,
initial_value: T): ReadableStore<T> {
const single = !Array.isArray(stores);
const stores_array: Array<ReadableStore<T>> = single
? [stores as ReadableStore<T>]
: stores as Array<ReadableStore<T>>;
const auto = fn.length < 2;
return readable(initial_value, (set) => {
let inited = false;
const values: T[] = [];
let pending = 0;
let cleanup = noop;
const sync = () => {
if (pending) {
return;
}
cleanup();
const result = fn(single ? values[0] : values, set);
if (auto) {
set(result as T);
} else {
cleanup = result as Unsubscriber || noop;
}
};
const unsubscribers = stores_array.map((store, i) => store.subscribe(
(value) => {
values[i] = value;
pending &= ~(1 << i);
if (inited) {
sync();
}
},
() => {
pending |= (1 << i);
}),
);
inited = true;
sync();
return function stop() {
run_all(unsubscribers);
cleanup();
};
});
}
export function get<T>(store: ReadableStore<T>): T {
let value: T | undefined;
store.subscribe((_: T) => value = _)();
return value as T;
}

@ -1,85 +0,0 @@
import { run_all, noop, get_store_value, safe_not_equal } from './internal';
export function readable(value, start) {
return {
subscribe: writable(value, start).subscribe
};
}
export function writable(value, start = noop) {
let stop;
const subscribers = [];
function set(new_value) {
if (safe_not_equal(value, new_value)) {
value = new_value;
if (!stop) return; // not ready
subscribers.forEach(s => s[1]());
subscribers.forEach(s => s[0](value));
}
}
function update(fn) {
set(fn(value));
}
function subscribe(run, invalidate = noop) {
const subscriber = [run, invalidate];
subscribers.push(subscriber);
if (subscribers.length === 1) stop = start(set) || noop;
run(value);
return () => {
const index = subscribers.indexOf(subscriber);
if (index !== -1) subscribers.splice(index, 1);
if (subscribers.length === 0) stop();
};
}
return { set, update, subscribe };
}
export function derived(stores, fn, initial_value) {
const single = !Array.isArray(stores);
if (single) stores = [stores];
const auto = fn.length < 2;
let value = {};
return readable(initial_value, set => {
let inited = false;
const values = [];
let pending = 0;
let cleanup = noop;
const sync = () => {
if (pending) return;
cleanup();
const result = fn(single ? values[0] : values, set);
if (auto) set(result);
else cleanup = result || noop;
};
const unsubscribers = stores.map((store, i) => store.subscribe(
value => {
values[i] = value;
pending &= ~(1 << i);
if (inited) sync();
},
() => {
pending |= (1 << i);
})
);
inited = true;
sync();
return function stop() {
run_all(unsubscribers);
cleanup();
};
});
}
export { get_store_value as get };

@ -7,7 +7,8 @@
"allowJs": true,
"lib": ["es5", "es6", "dom"],
"importHelpers": true,
"moduleResolution": "node"
"moduleResolution": "node",
"strict": true
},
"include": [
"src"

Loading…
Cancel
Save