svas 0.1.8 → 1.0.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.
@@ -30,10 +30,6 @@
30
30
  </div>
31
31
  {/if}
32
32
  {:else}
33
- {#if Array.isArray($store)}
34
- {@render awaited([...$store] as T)}
35
- {:else}
36
- {@render awaited($store)}
37
- {/if}
33
+ {@render awaited($store)}
38
34
  {/if}
39
35
  </div>
@@ -1,8 +1,15 @@
1
1
  import type { Props } from "./Async";
2
+ declare function $$render<T>(): {
3
+ props: Props<T>;
4
+ exports: {};
5
+ bindings: "";
6
+ slots: {};
7
+ events: {};
8
+ };
2
9
  declare class __sveltets_Render<T> {
3
- props(): Props<T>;
4
- events(): {};
5
- slots(): {};
10
+ props(): ReturnType<typeof $$render<T>>['props'];
11
+ events(): ReturnType<typeof $$render<T>>['events'];
12
+ slots(): ReturnType<typeof $$render<T>>['slots'];
6
13
  bindings(): "";
7
14
  exports(): {};
8
15
  }
@@ -4,40 +4,32 @@ import type { GetOptions, Values } from './values';
4
4
  export declare class Collection<T extends Identifiable, E extends Error = Error> implements Readable<Maybe<T[], E>> {
5
5
  private readonly store;
6
6
  private readonly values?;
7
- private readonly fetch;
8
- private readonly map;
9
- private readonly sort;
7
+ private readonly request;
10
8
  private readonly revalidate;
11
9
  private readonly stale;
12
10
  private timestamp;
13
11
  constructor(options: Options<T, E>);
14
12
  subscribe(run: Subscriber<Maybe<T[], E>>, invalidate?: () => void): Unsubscriber;
15
- add<I = T>(item: Input<T, typeof this.map, I>): void;
13
+ add(item: T): void;
16
14
  get(id: string, options?: GetOptions): Readable<Maybe<T, E>>;
17
15
  extract(id: string): T | null;
18
16
  delete(id: string): void;
19
- set<I = T>(item: Input<T, typeof this.map, I>, options?: SetOptions): Readable<T | E>;
20
- preset<I = T>(item: Input<T, typeof this.map, I>): void;
21
- reset(id: string): void;
17
+ set(item: T, options?: SetOptions): void;
22
18
  update(id: string, update: (item: T) => T | void, options?: SetOptions): void;
23
19
  sync(): this;
24
- replace<I = T>(items: Array<Input<T, typeof this.map, I>>): void;
20
+ fetch(): Promise<this>;
21
+ replace(items: T[]): void;
25
22
  private refresh;
26
23
  private persist;
27
24
  private bind;
28
25
  private clear;
29
26
  }
30
- type Input<T, M, Default> = M extends (arg: infer P) => T ? P : Default;
31
27
  interface Options<T = unknown, E extends Error = Error> {
32
28
  /** Fetches the collection. */
33
- get?: () => Promise<any[] | E>;
34
- /** Maps the fetched item to the type of the collection. */
35
- map?: (item: any) => T;
36
- /** Sorting function applied on updates. */
37
- sort?: (a: T, b: T) => number;
38
- /** Time in milliseconds before revalidating the collection. */
29
+ get?: () => Promise<T[] | E>;
30
+ /** Time in milliseconds before revalidating the collection. Defaults to 300 seconds. */
39
31
  revalidate?: number;
40
- /** Whether to keep the collection while revalidating. */
32
+ /** Whether to keep the collection while revalidating. Defaults to false. */
41
33
  stale?: boolean;
42
34
  /** Values store. */
43
35
  values?: Values<T, E>;
@@ -50,14 +42,8 @@ export interface Identifiable {
50
42
  id: string;
51
43
  }
52
44
  export interface SetOptions {
53
- /** Whether to sort the collection after setting the item. Defaults to true. */
54
- sort?: boolean;
55
45
  /** Whether to add the item to the collection if it does not exist. Defaults to false. */
56
46
  add?: boolean;
57
- /** Whether value is transient. Defaults to false. */
58
- stash?: boolean;
59
- /** Whether to sync the collection values after setting the item. Defaults to true. */
60
- sync?: boolean;
61
47
  }
62
48
  export declare function collection<T extends Identifiable, E extends Error = Error>(options: Options<T, E>): Collection<T, E>;
63
49
  export {};
@@ -1,47 +1,35 @@
1
1
  import { writable } from 'svelte/store';
2
- import { browser } from '$app/environment';
3
2
  export class Collection {
4
3
  store;
5
4
  values;
6
- fetch;
7
- map;
8
- sort;
5
+ request;
9
6
  revalidate;
10
7
  stale;
11
8
  timestamp = 0;
12
9
  constructor(options) {
13
10
  this.store = writable(null);
14
11
  this.values = options.values;
15
- this.fetch = options.get;
16
- this.map = options.map;
17
- this.sort = options.sort;
12
+ this.request = options.get;
18
13
  this.revalidate = options.revalidate ?? DEFAULTS.revalidate;
19
14
  this.stale = options.stale ?? DEFAULTS.stale;
20
- if (browser) {
21
- if (options.persist !== undefined)
22
- this.persist(options.persist);
23
- if (options.bind !== undefined)
24
- this.bind(options.bind);
25
- }
15
+ if (options.persist !== undefined)
16
+ this.persist(options.persist);
17
+ if (options.bind !== undefined)
18
+ this.bind(options.bind);
26
19
  }
27
20
  subscribe(run, invalidate) {
28
21
  this.sync();
29
22
  return this.store.subscribe(run, invalidate);
30
23
  }
31
24
  add(item) {
32
- const value = this.map?.(item) ?? item;
33
- this.values?.set(value.id, value);
25
+ this.values?.set(item.id, item);
34
26
  this.store.update((items) => {
35
27
  if (items === null || items instanceof Error)
36
- return [value];
37
- else {
38
- if (items.find((item) => item.id === value.id) !== undefined)
39
- return items;
40
- items.unshift(value);
41
- if (this.sort !== undefined)
42
- items.sort(this.sort);
28
+ return [item];
29
+ else if (items.find((i) => i.id === item.id) !== undefined)
43
30
  return items;
44
- }
31
+ else
32
+ return [item, ...items];
45
33
  });
46
34
  }
47
35
  get(id, options) {
@@ -59,37 +47,20 @@ export class Collection {
59
47
  this.store.update((items) => {
60
48
  if (items === null || items instanceof Error)
61
49
  return items;
62
- return items.filter((item) => item.id !== id);
50
+ else
51
+ return items.filter((item) => item.id !== id);
63
52
  });
64
53
  }
65
54
  set(item, options) {
66
- const value = this.map?.(item) ?? item;
67
55
  this.store.update((items) => {
68
56
  if (items === null || items instanceof Error)
69
57
  return [item];
70
- const index = items.findIndex((i) => i.id === value.id);
58
+ const index = items.findIndex((i) => i.id === item.id);
71
59
  if (index === -1)
72
- return options?.add === true ? [value, ...items] : items;
73
- items[index] = value;
74
- if (this.sort !== undefined && options?.sort !== false)
75
- items.sort(this.sort);
60
+ return options?.add === true ? [item, ...items] : items;
61
+ items[index] = item;
76
62
  return items;
77
63
  });
78
- if (options?.sync === false)
79
- return this.values?.get(value.id);
80
- else
81
- return this.values?.set(value.id, value, options);
82
- }
83
- preset(item) {
84
- this.set(item, { stash: true });
85
- }
86
- reset(id) {
87
- if (this.values === undefined)
88
- throw new Error('Collection: values is not defined');
89
- const value = this.values?.reset(id);
90
- if (value === null || value instanceof Error)
91
- return;
92
- this.set(value, { sync: false });
93
64
  }
94
65
  update(id, update, options) {
95
66
  if (this.values === undefined)
@@ -105,30 +76,35 @@ export class Collection {
105
76
  if (stale) {
106
77
  if (!this.stale)
107
78
  this.clear();
108
- this.refresh();
79
+ void this.refresh();
109
80
  }
110
81
  return this;
111
82
  }
83
+ async fetch() {
84
+ await this.refresh();
85
+ return this;
86
+ }
112
87
  replace(items) {
113
- const values = this.map === undefined ? items : items.map((item) => this.map(item));
88
+ const values = items;
114
89
  this.store.set(values);
115
90
  this.timestamp = Date.now();
116
91
  if (this.values !== undefined)
117
92
  for (const value of values)
118
93
  this.values.set(value.id, value);
119
94
  }
120
- refresh() {
121
- if (this.fetch === undefined)
95
+ async refresh() {
96
+ if (this.request === undefined)
122
97
  return;
123
- this.fetch().then((items) => {
124
- if (!(items instanceof Error))
125
- this.replace(items);
126
- else
127
- this.store.set(items);
128
- });
98
+ const items = await this.request();
99
+ if (!(items instanceof Error))
100
+ this.replace(items);
101
+ else
102
+ this.store.set(items);
129
103
  this.timestamp = Date.now();
130
104
  }
131
105
  persist(key) {
106
+ if (typeof window === 'undefined')
107
+ return;
132
108
  const stored = localStorage.getItem(key);
133
109
  if (stored !== null) {
134
110
  const items = JSON.parse(stored);
package/dist/ensure.d.ts CHANGED
@@ -1,3 +1,3 @@
1
- import type { Maybe } from './reflection/Maybe';
1
+ import type { Maybe } from './Maybe';
2
2
  import { type Readable } from 'svelte/store';
3
3
  export declare function ensure<T>(store: Readable<Maybe<T>>): T;
package/dist/sync.d.ts CHANGED
@@ -1,6 +1,5 @@
1
1
  import type { Collection, Identifiable, SetOptions } from './collection';
2
- export declare function sync<T extends Comparable, I = T>(input: Input<T, Parameters<Collection<T>['add']>[0], I>, collection: Collection<T>, options?: Options): void;
3
- type Input<T, M, Default> = M extends (arg: infer P) => T ? P : Default;
2
+ export declare function sync<T extends Comparable>(tobe: T, collection: Collection<T>, options?: Options): void;
4
3
  interface Comparable extends Identifiable {
5
4
  _version: number;
6
5
  _deleted?: number | null;
package/dist/sync.js CHANGED
@@ -1,5 +1,4 @@
1
- export function sync(input, collection, options) {
2
- const tobe = input;
1
+ export function sync(tobe, collection, options) {
3
2
  if (tobe._deleted !== null && tobe._deleted !== undefined) {
4
3
  collection.delete(tobe.id);
5
4
  return;
package/dist/value.d.ts CHANGED
@@ -1,10 +1,9 @@
1
1
  import { type Readable, type Subscriber, type Unsubscriber, type Updater, type Writable } from 'svelte/store';
2
- type Input<T, M, Default> = M extends (arg: infer P) => T ? P : Default;
3
2
  declare class Value<T> implements Writable<T | null> {
4
3
  private readonly store;
5
- private readonly map?;
4
+ private readonly default;
6
5
  constructor(options: Options<T>);
7
- set<I = T>(value: Input<T, typeof this.map, I> | null): void;
6
+ set(value: T | null): void;
8
7
  update(updater: Updater<T | null>): void;
9
8
  subscribe(run: Subscriber<T | null>, invalidate?: () => void): Unsubscriber;
10
9
  extract(): T | null;
@@ -25,10 +24,6 @@ interface Options<T> {
25
24
  * Nullify values when the bound store is null.
26
25
  */
27
26
  bind?: Readable<unknown | null>;
28
- /**
29
- * Maps values on set.
30
- */
31
- map?: (item: any) => T;
32
27
  /**
33
28
  * Default value.
34
29
  */
package/dist/value.js CHANGED
@@ -1,33 +1,22 @@
1
1
  import { get, writable } from 'svelte/store';
2
- import { browser } from '$app/environment';
3
2
  class Value {
4
3
  store;
5
- map;
4
+ default;
6
5
  constructor(options) {
7
- const persist = browser && options.persist !== undefined;
8
- const def = options.default ?? null;
9
- this.store = persist
10
- ? persistent(options.persist, def, options.session)
11
- : writable(def);
12
- if (browser) {
13
- if (options.bind)
14
- this.bind(options.bind);
15
- if (options.map)
16
- this.map = options.map;
17
- }
6
+ this.default = options.default ?? null;
7
+ this.store = options.persist === undefined || typeof window === 'undefined'
8
+ ? writable(this.default)
9
+ : persistent(options.persist, this.default, options.session);
10
+ if (options.bind)
11
+ this.bind(options.bind);
18
12
  }
19
13
  set(value) {
20
- if (value !== null && this.map)
21
- value = this.map(value);
22
14
  this.store.set(value);
23
15
  }
24
16
  update(updater) {
25
17
  this.store.update((value) => {
26
18
  const updated = updater(value);
27
- if (this.map)
28
- return this.map(updated);
29
- else
30
- return updated;
19
+ return updated;
31
20
  });
32
21
  }
33
22
  subscribe(run, invalidate) {
@@ -39,7 +28,7 @@ class Value {
39
28
  bind(store) {
40
29
  store.subscribe((value) => {
41
30
  if (value === null)
42
- this.store.set(null);
31
+ this.store.set(this.default);
43
32
  });
44
33
  }
45
34
  }
package/dist/values.d.ts CHANGED
@@ -4,7 +4,6 @@ declare class Values<T, E extends Error = Error> {
4
4
  readonly persistent: boolean;
5
5
  private readonly values;
6
6
  private readonly fetch;
7
- private readonly map;
8
7
  private readonly revalidate;
9
8
  private readonly permanent;
10
9
  private readonly stale;
@@ -12,7 +11,7 @@ declare class Values<T, E extends Error = Error> {
12
11
  private ready;
13
12
  private dumping;
14
13
  constructor(options: Options<T, E>);
15
- set<I = T>(key: string, item: Input<T, typeof this.map, I> | E, options?: SetOptions): Readable<T | E>;
14
+ set(key: string, item: T | E, options?: SetOptions): Readable<T | E>;
16
15
  /**
17
16
  * Restores persistent value.
18
17
  */
@@ -27,16 +26,11 @@ declare class Values<T, E extends Error = Error> {
27
26
  private load;
28
27
  private bind;
29
28
  }
30
- type Input<T, M, Default> = M extends (arg: infer P) => T ? P : Default;
31
29
  interface Options<T = unknown, E extends Error = Error> {
32
30
  /**
33
31
  * Fetches the value
34
32
  */
35
- get?: (key: string) => Promise<Exclude<any, Error> | E>;
36
- /**
37
- * Maps the fetched value
38
- */
39
- map?: (item: any) => T;
33
+ get?: (key: string) => Promise<T | E>;
40
34
  /**
41
35
  * Time in milliseconds before revalidating the value.
42
36
  * Default is 60 seconds.
package/dist/values.js CHANGED
@@ -1,10 +1,8 @@
1
- import { browser } from '$app/environment';
2
1
  import { get, writable } from 'svelte/store';
3
2
  class Values {
4
3
  persistent;
5
4
  values = {};
6
5
  fetch;
7
- map;
8
6
  revalidate;
9
7
  permanent;
10
8
  stale;
@@ -13,20 +11,17 @@ class Values {
13
11
  dumping = null;
14
12
  constructor(options) {
15
13
  this.fetch = options.get;
16
- this.map = options.map;
17
14
  this.revalidate = options.revalidate ?? DEFAULTS.revalidate;
18
15
  this.permanent = options.permanent ?? DEFAULTS.permanent;
19
16
  this.stale = options.stale ?? DEFAULTS.stale;
20
17
  this.persist = options.persist;
21
18
  this.persistent = this.persist !== undefined;
22
- if (browser) {
23
- this.load();
24
- if (options.bind !== undefined)
25
- this.bind(options.bind);
26
- }
19
+ this.load();
20
+ if (options.bind !== undefined)
21
+ this.bind(options.bind);
27
22
  }
28
23
  set(key, item, options) {
29
- const value = this.map?.(item) ?? item;
24
+ const value = item;
30
25
  const entry = this.values[key] ?? (this.values[key] = this.create(value));
31
26
  if (options?.stash === true)
32
27
  this.stash(key);
@@ -100,7 +95,7 @@ class Values {
100
95
  entry.stash ??= get(store);
101
96
  }
102
97
  dump(delay = true) {
103
- if (this.persist === undefined || !browser)
98
+ if (this.persist === undefined || typeof window === 'undefined')
104
99
  return;
105
100
  if (delay) {
106
101
  this.dumping ??= setTimeout(() => this.dump(false), DUMP_GAP);
@@ -120,7 +115,7 @@ class Values {
120
115
  localStorage.setItem(this.persist, JSON.stringify(data));
121
116
  }
122
117
  load() {
123
- if (this.persist === undefined)
118
+ if (this.persist === undefined || typeof window === 'undefined')
124
119
  return;
125
120
  const data = localStorage.getItem(this.persist);
126
121
  if (data === null)
package/package.json CHANGED
@@ -1,6 +1,7 @@
1
1
  {
2
2
  "name": "svas",
3
- "version": "0.1.8",
3
+ "version": "1.0.0",
4
+ "repository": "https://github.com/temich/svas",
4
5
  "scripts": {
5
6
  "dev": "vite dev",
6
7
  "build": "vite build && npm run prepack",
@@ -9,7 +10,8 @@
9
10
  "prepack": "svelte-kit sync && svelte-package && publint",
10
11
  "check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json",
11
12
  "check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch",
12
- "lint": "eslint ."
13
+ "lint": "eslint .",
14
+ "bump": "npx -y npm-check-updates --target minor -u"
13
15
  },
14
16
  "files": [
15
17
  "dist",
@@ -30,27 +32,33 @@
30
32
  },
31
33
  "peerDependencies": {
32
34
  "@lucide/svelte": "*",
33
- "svelte": "^5.0.0",
34
- "@sveltejs/kit": "*"
35
+ "@sveltejs/kit": "*",
36
+ "svelte": "^5.0.0"
35
37
  },
36
38
  "devDependencies": {
37
- "@eslint/compat": "^1.2.9",
38
- "@eslint/js": "^9.18.0",
39
- "@sveltejs/adapter-auto": "^6.0.0",
40
- "@sveltejs/kit": "^2.16.0",
41
- "@sveltejs/package": "^2.0.0",
42
- "@sveltejs/vite-plugin-svelte": "^5.0.0",
43
- "autoprefixer": "^10.4.20",
44
- "eslint": "^9.18.0",
45
- "eslint-plugin-svelte": "^3.0.0",
46
- "globals": "^16.0.0",
47
- "publint": "^0.3.2",
48
- "svelte": "^5.0.0",
49
- "svelte-check": "^4.0.0",
50
- "tailwindcss": "^3.4.17",
51
- "typescript": "^5.0.0",
52
- "typescript-eslint": "^8.20.0",
53
- "vite": "^6.2.6"
39
+ "@eslint/compat": "^2.0.0",
40
+ "@eslint/js": "^9.39.1",
41
+ "@semantic-release/changelog": "^6.0.3",
42
+ "@semantic-release/commit-analyzer": "^13.0.1",
43
+ "@semantic-release/git": "^10.0.1",
44
+ "@semantic-release/github": "^12.0.2",
45
+ "@semantic-release/npm": "^13.1.2",
46
+ "@semantic-release/release-notes-generator": "^14.1.0",
47
+ "@sveltejs/adapter-auto": "^7.0.0",
48
+ "@sveltejs/kit": "^2.49.2",
49
+ "@sveltejs/package": "^2.5.7",
50
+ "@sveltejs/vite-plugin-svelte": "^6.2.1",
51
+ "autoprefixer": "^10.4.22",
52
+ "eslint": "^9.39.1",
53
+ "eslint-plugin-svelte": "^3.13.1",
54
+ "globals": "^16.5.0",
55
+ "publint": "^0.3.15",
56
+ "svelte": "^5.45.8",
57
+ "svelte-check": "^4.3.4",
58
+ "tailwindcss": "^4.1.17",
59
+ "typescript": "^5.9.3",
60
+ "typescript-eslint": "^8.49.0",
61
+ "vite": "^7.2.7"
54
62
  },
55
63
  "keywords": [
56
64
  "svelte"