@azure-net/kit 5.2.0 → 5.3.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.
@@ -9,12 +9,40 @@ export type CookieOptions = {
9
9
  priority?: 'low' | 'medium' | 'high' | undefined;
10
10
  partitioned?: boolean | undefined;
11
11
  };
12
+ /** Cookie operations with shared defaults and request-local resolution at call time. */
13
+ export declare class UniversalCookieInstance {
14
+ private readonly defaults;
15
+ constructor(options?: CookieOptions);
16
+ set<T>(name: string, value: T, options?: CookieOptions): void;
17
+ get<T = string>(name: string): T | undefined;
18
+ getAll<T = Record<string, unknown>>(): T | undefined;
19
+ has(name: string): boolean;
20
+ delete(name: string, options?: CookieOptions): void;
21
+ clear(options?: CookieOptions): void;
22
+ toCredentials(): string;
23
+ createNamedInstance<T = string>(name: string): UniversalNamedCookieInstance<T>;
24
+ }
25
+ /** Type-safe operations for one cookie name. */
26
+ export declare class UniversalNamedCookieInstance<T = string> {
27
+ readonly name: string;
28
+ private readonly cookies;
29
+ constructor(name: string, cookies: UniversalCookieInstance);
30
+ set(value: T, options?: CookieOptions): void;
31
+ get(): T | undefined;
32
+ has(): boolean;
33
+ delete(options?: CookieOptions): void;
34
+ clear(options?: CookieOptions): void;
35
+ }
12
36
  /**
13
37
  * Utility class for managing cookies in svelte ssr (browser and server).
14
38
  * Supports setting, getting, deleting, checking, and clearing cookies.
15
39
  * All methods are static and operate without creating instances.
16
40
  */
17
41
  export declare class UniversalCookie {
42
+ /** Creates reusable cookie operations with shared defaults. */
43
+ static createInstance(options?: CookieOptions): UniversalCookieInstance;
44
+ /** Creates reusable operations bound to one cookie name. */
45
+ static createNamedInstance<T = string>(name: string, options?: CookieOptions): UniversalNamedCookieInstance<T>;
18
46
  private static serialize;
19
47
  private static deserialize;
20
48
  /**
@@ -1,11 +1,81 @@
1
1
  import { BROWSER, Cookies } from '../../external/tools/index.js';
2
2
  import { RequestContext } from '../../external/edges/ServerContext.js';
3
+ const cloneCookieOptions = (options) => ({
4
+ ...options,
5
+ expires: options.expires instanceof Date ? new Date(options.expires) : options.expires
6
+ });
7
+ const mergeCookieOptions = (defaults, overrides) => overrides ? { ...defaults, ...overrides } : defaults;
8
+ /** Cookie operations with shared defaults and request-local resolution at call time. */
9
+ export class UniversalCookieInstance {
10
+ defaults;
11
+ constructor(options = {}) {
12
+ this.defaults = cloneCookieOptions(options);
13
+ }
14
+ set(name, value, options) {
15
+ UniversalCookie.set(name, value, mergeCookieOptions(this.defaults, options));
16
+ }
17
+ get(name) {
18
+ return UniversalCookie.get(name);
19
+ }
20
+ getAll() {
21
+ return UniversalCookie.getAll();
22
+ }
23
+ has(name) {
24
+ return UniversalCookie.has(name);
25
+ }
26
+ delete(name, options) {
27
+ UniversalCookie.delete(name, mergeCookieOptions(this.defaults, options));
28
+ }
29
+ clear(options) {
30
+ UniversalCookie.clear(mergeCookieOptions(this.defaults, options));
31
+ }
32
+ toCredentials() {
33
+ return UniversalCookie.toCredentials();
34
+ }
35
+ createNamedInstance(name) {
36
+ return new UniversalNamedCookieInstance(name, this);
37
+ }
38
+ }
39
+ /** Type-safe operations for one cookie name. */
40
+ export class UniversalNamedCookieInstance {
41
+ name;
42
+ cookies;
43
+ constructor(name, cookies) {
44
+ if (!name)
45
+ throw new TypeError('Cookie name must not be empty.');
46
+ this.name = name;
47
+ this.cookies = cookies;
48
+ }
49
+ set(value, options) {
50
+ this.cookies.set(this.name, value, options);
51
+ }
52
+ get() {
53
+ return this.cookies.get(this.name);
54
+ }
55
+ has() {
56
+ return this.cookies.has(this.name);
57
+ }
58
+ delete(options) {
59
+ this.cookies.delete(this.name, options);
60
+ }
61
+ clear(options) {
62
+ this.delete(options);
63
+ }
64
+ }
3
65
  /**
4
66
  * Utility class for managing cookies in svelte ssr (browser and server).
5
67
  * Supports setting, getting, deleting, checking, and clearing cookies.
6
68
  * All methods are static and operate without creating instances.
7
69
  */
8
70
  export class UniversalCookie {
71
+ /** Creates reusable cookie operations with shared defaults. */
72
+ static createInstance(options = {}) {
73
+ return new UniversalCookieInstance(options);
74
+ }
75
+ /** Creates reusable operations bound to one cookie name. */
76
+ static createNamedInstance(name, options = {}) {
77
+ return this.createInstance(options).createNamedInstance(name);
78
+ }
9
79
  static serialize(value) {
10
80
  if (typeof value === 'string')
11
81
  return value;
@@ -1,2 +1,12 @@
1
1
  import { EventBus } from '../../external/tools/index.js';
2
- export declare const AppEvents: () => EventBus<any>;
2
+ declare global {
3
+ namespace App {
4
+ interface CustomEvents {
5
+ readonly __azureNetEvents__?: never;
6
+ }
7
+ }
8
+ }
9
+ export type AppEventsList = App.CustomEvents extends {
10
+ list: infer TEvents extends object;
11
+ } ? TEvents : Record<never, never>;
12
+ export declare const AppEvents: () => EventBus<AppEventsList>;
@@ -1,6 +1,3 @@
1
1
  import { EventBus } from '../../external/tools/index.js';
2
2
  import { createPresenter } from '../../external/edges/Edges.js';
3
- export const AppEvents = createPresenter(() => {
4
- const appEventBus = new EventBus({});
5
- return appEventBus;
6
- });
3
+ export const AppEvents = createPresenter(() => new EventBus({}));
@@ -1,4 +1,4 @@
1
- export { UniversalCookie, type CookieOptions } from './cookie/index.js';
1
+ export { UniversalCookie, UniversalCookieInstance, UniversalNamedCookieInstance, type CookieOptions } from './cookie/index.js';
2
2
  export { BackgroundTask } from './background-task/index.js';
3
3
  export { AppEvents } from './event-bus/index.js';
4
4
  export { ClassMirror } from './class-mirror/index.js';
@@ -1,4 +1,4 @@
1
- export { UniversalCookie } from './cookie/index.js';
1
+ export { UniversalCookie, UniversalCookieInstance, UniversalNamedCookieInstance } from './cookie/index.js';
2
2
  export { BackgroundTask } from './background-task/index.js';
3
3
  export { AppEvents } from './event-bus/index.js';
4
4
  export { ClassMirror } from './class-mirror/index.js';
@@ -124,6 +124,9 @@ export const createAsyncSignal = (handler, options = {}) => {
124
124
  }
125
125
  await start('manual');
126
126
  };
127
+ const refresh = async () => {
128
+ await start('manual');
129
+ };
127
130
  if (BROWSER) {
128
131
  const signalKey = key ?? asyncSignalManager.generateKey();
129
132
  const callback = (source) => start(source);
@@ -163,7 +166,7 @@ export const createAsyncSignal = (handler, options = {}) => {
163
166
  return start('auto');
164
167
  },
165
168
  execute,
166
- refresh: execute,
169
+ refresh,
167
170
  reset: () => {
168
171
  currentRunId += 1;
169
172
  abortController?.abort();
@@ -1,24 +1,55 @@
1
1
  import { untrack } from 'svelte';
2
+ import { ObjectUtil } from '../../external/tools/index.js';
2
3
  import { cloneStateValue } from '../shared/cloneStateValue.js';
4
+ const trackDeep = (value, seen = new WeakSet()) => {
5
+ if (value === null || typeof value !== 'object' || seen.has(value))
6
+ return;
7
+ seen.add(value);
8
+ if (Array.isArray(value)) {
9
+ for (const item of value)
10
+ trackDeep(item, seen);
11
+ return;
12
+ }
13
+ if (value instanceof Map) {
14
+ for (const [key, item] of value) {
15
+ trackDeep(key, seen);
16
+ trackDeep(item, seen);
17
+ }
18
+ return;
19
+ }
20
+ if (value instanceof Set) {
21
+ for (const item of value)
22
+ trackDeep(item, seen);
23
+ return;
24
+ }
25
+ const prototype = Object.getPrototypeOf(value);
26
+ if (prototype !== Object.prototype && prototype !== null)
27
+ return;
28
+ for (const key of Reflect.ownKeys(value)) {
29
+ trackDeep(Reflect.get(value, key), seen);
30
+ }
31
+ };
3
32
  export const createQuery = (initialValue, options) => {
4
33
  const baseInitial = cloneStateValue(initialValue);
5
34
  let data = $state(cloneStateValue(baseInitial));
6
- const includeKeys = options?.onChange?.include ?? [];
35
+ const includeKeys = [...new Set(options?.onChange?.include ?? [])];
7
36
  const hasWatch = Boolean(options?.onChange?.handler) && includeKeys.length > 0;
8
- const lastValues = new Map();
37
+ const lastSnapshots = new Map();
9
38
  let onChangeController = null;
10
39
  let onChangeRunId = 0;
11
40
  if (hasWatch) {
12
41
  includeKeys.forEach((key) => {
13
- lastValues.set(key, data[key]);
42
+ lastSnapshots.set(key, cloneStateValue(data[key]));
14
43
  });
15
44
  $effect(() => {
16
45
  const changedKeys = [];
17
46
  includeKeys.forEach((key) => {
18
47
  const nextValue = data[key];
19
- if (!Object.is(lastValues.get(key), nextValue)) {
48
+ trackDeep(nextValue);
49
+ const nextSnapshot = cloneStateValue(nextValue);
50
+ if (!ObjectUtil.equals(lastSnapshots.get(key), nextSnapshot)) {
20
51
  changedKeys.push(key);
21
- lastValues.set(key, nextValue);
52
+ lastSnapshots.set(key, nextSnapshot);
22
53
  }
23
54
  });
24
55
  if (!changedKeys.length)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@azure-net/kit",
3
- "version": "5.2.0",
3
+ "version": "5.3.0",
4
4
  "license": "MIT",
5
5
  "author": "Pixel1917",
6
6
  "description": "Universal toolkit and library collection, developed as part of the Azure-net ecosystem",
@@ -126,8 +126,9 @@
126
126
  "format": "prettier --write .",
127
127
  "lint": "prettier --check . && eslint .",
128
128
  "test:unit": "vitest --config vitest.config.ts",
129
+ "test:client": "vitest --config vitest.client.config.ts",
129
130
  "test:integration": "vitest --config vitest.integration.config.ts --run",
130
- "test": "pnpm test:unit -- --run && pnpm test:integration && pnpm test:e2e",
131
+ "test": "pnpm test:unit -- --run && pnpm test:client -- --run && pnpm test:integration && pnpm test:e2e",
131
132
  "test:e2e": "playwright test",
132
133
  "commit": "pnpm format && git add ."
133
134
  }