svas 1.5.1 → 1.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/sync.d.ts CHANGED
@@ -1,8 +1,12 @@
1
- import type { Collection, Identifiable, SetOptions } from './collection';
2
- export declare function sync<T extends Comparable>(collection: Collection<T>, tobe: T, options?: Options): void;
1
+ import { Collection, type Identifiable, type SetOptions } from './collection';
2
+ import { Value } from './value';
3
+ export declare function sync<T extends Comparable>(store: Collection<T> | Value<T>, tobe: T, options?: Options): void;
3
4
  interface Comparable extends Identifiable {
4
5
  _version: number;
5
6
  _deleted?: number | null;
6
7
  }
7
- type Options = SetOptions;
8
+ interface Options extends SetOptions {
9
+ /** Whether to delete the item `_deleted` is set. Defaults to `true`. */
10
+ delete?: boolean;
11
+ }
8
12
  export {};
package/dist/sync.js CHANGED
@@ -1,5 +1,13 @@
1
- export function sync(collection, tobe, options) {
2
- if (tobe._deleted !== null && tobe._deleted !== undefined) {
1
+ import { Collection } from './collection';
2
+ import { Value } from './value';
3
+ export function sync(store, tobe, options) {
4
+ if (store instanceof Collection)
5
+ syncCollection(store, tobe, options);
6
+ else if (store instanceof Value)
7
+ syncValue(store, tobe);
8
+ }
9
+ function syncCollection(collection, tobe, options) {
10
+ if (tobe._deleted !== null && tobe._deleted !== undefined && options?.delete !== false) {
3
11
  collection.delete(tobe.id);
4
12
  return;
5
13
  }
@@ -8,6 +16,11 @@ export function sync(collection, tobe, options) {
8
16
  collection.add(tobe);
9
17
  else if (asis._version < tobe._version)
10
18
  collection.set(tobe, { add: true, ...options });
11
- else
12
- console.debug('Sync skipped', tobe);
19
+ }
20
+ function syncValue(value, tobe) {
21
+ const asis = value.extract();
22
+ if (asis === null)
23
+ value.set(tobe);
24
+ else if (asis._version < tobe._version)
25
+ value.set(tobe);
13
26
  }
package/dist/value.d.ts CHANGED
@@ -1,16 +1,27 @@
1
1
  import { type Readable, type Subscriber, type Unsubscriber, type Updater, type Writable } from 'svelte/store';
2
- declare class Value<T> implements Writable<T | null> {
2
+ export declare class Value<T> implements Writable<T | null> {
3
3
  private readonly store;
4
4
  private readonly default;
5
+ private readonly request;
6
+ private readonly revalidate;
7
+ private timestamp;
5
8
  constructor(options: Options<T>);
6
9
  set(value: T | null): void;
7
10
  update(updater: Updater<T | null>): void;
8
11
  subscribe(run: Subscriber<T | null>, invalidate?: () => void): Unsubscriber;
9
12
  extract(): T | null;
13
+ sync(): void;
14
+ private refresh;
10
15
  private bind;
11
16
  }
12
17
  export declare function value<T>(options?: Options<T>): Value<T>;
13
- interface Options<T> {
18
+ interface Options<T = unknown> {
19
+ /**
20
+ * Fetches the value
21
+ */
22
+ get?: () => Promise<T | Error>;
23
+ /** Time in milliseconds before revalidating the collection. Defaults to 300 seconds. */
24
+ revalidate?: number;
14
25
  /**
15
26
  * Key to persist the collection.
16
27
  */
package/dist/value.js CHANGED
@@ -1,9 +1,14 @@
1
1
  import { get, writable } from 'svelte/store';
2
- class Value {
2
+ export class Value {
3
3
  store;
4
4
  default;
5
+ request;
6
+ revalidate;
7
+ timestamp = 0;
5
8
  constructor(options) {
6
9
  this.default = options.default ?? null;
10
+ this.request = options.get;
11
+ this.revalidate = options.revalidate ?? DEFAULTS.revalidate;
7
12
  this.store = options.persist === undefined || typeof window === 'undefined'
8
13
  ? writable(this.default)
9
14
  : persistent(options.persist, this.default, options.session);
@@ -20,11 +25,27 @@ class Value {
20
25
  });
21
26
  }
22
27
  subscribe(run, invalidate) {
28
+ this.sync();
23
29
  return this.store.subscribe(run, invalidate);
24
30
  }
25
31
  extract() {
26
32
  return get(this.store);
27
33
  }
34
+ sync() {
35
+ if (this.request === undefined)
36
+ return;
37
+ const stale = this.timestamp + this.revalidate < Date.now();
38
+ if (stale)
39
+ void this.refresh();
40
+ }
41
+ async refresh() {
42
+ if (this.request === undefined)
43
+ return;
44
+ this.timestamp = Date.now();
45
+ const value = await this.request();
46
+ if (!(value instanceof Error))
47
+ this.set(value);
48
+ }
28
49
  bind(store) {
29
50
  store.subscribe((value) => {
30
51
  if (value === null)
@@ -58,3 +79,6 @@ function load(key) {
58
79
  return null;
59
80
  }
60
81
  }
82
+ const DEFAULTS = {
83
+ revalidate: 300_000,
84
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "svas",
3
- "version": "1.5.1",
3
+ "version": "1.7.0",
4
4
  "repository": "https://github.com/temich/svas",
5
5
  "scripts": {
6
6
  "dev": "vite dev",