@tstdl/base 0.90.59 → 0.90.61

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/.eslintrc.json CHANGED
@@ -33,7 +33,7 @@
33
33
  "eqeqeq": ["off"],
34
34
  "explicit-function-return-type": ["off"],
35
35
  "explicit-member-accessibility": ["off"],
36
- "func-style": ["error", "declaration", { "allowArrowFunctions": true }],
36
+ "func-style": ["warn", "declaration", { "allowArrowFunctions": true }],
37
37
  "id-length": ["off"],
38
38
  "init-declarations": ["off"],
39
39
  "line-comment-position": ["off"],
@@ -47,7 +47,7 @@
47
47
  "no-bitwise": ["off"],
48
48
  "no-case-declarations": ["warn"],
49
49
  "no-confusing-void-expression": ["off"],
50
- "no-constant-condition": ["error", { "checkLoops": false }],
50
+ "no-constant-condition": ["warn", { "checkLoops": false }],
51
51
  "no-continue": ["off"],
52
52
  "no-duplicate-imports": ["off"],
53
53
  "no-empty-interface": ["off"],
@@ -67,7 +67,7 @@
67
67
  "no-unused-vars": ["off"],
68
68
  "no-use-before-define": ["off"],
69
69
  "no-void": ["warn", { "allowAsStatement": true }],
70
- "one-var": ["error", "never"],
70
+ "one-var": ["warn", "never"],
71
71
  "prefer-arrow-callback": ["warn"],
72
72
  "prefer-destructuring": ["off"],
73
73
  "prefer-named-capture-group": ["warn"],
@@ -76,27 +76,27 @@
76
76
  "sort-keys": ["off"],
77
77
  "sort-type-constituents": ["off"],
78
78
 
79
- "@typescript-eslint/ban-types": ["error"],
79
+ "@typescript-eslint/ban-types": ["warn"],
80
80
  "@typescript-eslint/class-methods-use-this": ["warn", { "ignoreOverrideMethods": true, "ignoreClassesThatImplementAnInterface": true }],
81
81
  "@typescript-eslint/consistent-type-definitions": ["off"],
82
82
  "@typescript-eslint/consistent-type-imports": ["warn", { "prefer": "type-imports", "fixStyle": "inline-type-imports", "disallowTypeAnnotations": false }],
83
- "@typescript-eslint/explicit-function-return-type": ["error", { "allowExpressions": true, "allowFunctionsWithoutTypeParameters": true }],
84
- "@typescript-eslint/explicit-member-accessibility": ["error", { "accessibility": "no-public" }],
83
+ "@typescript-eslint/explicit-function-return-type": ["warn", { "allowExpressions": true, "allowFunctionsWithoutTypeParameters": true }],
84
+ "@typescript-eslint/explicit-member-accessibility": ["warn", { "accessibility": "no-public" }],
85
85
  "@typescript-eslint/init-declarations": ["off"],
86
86
  "@typescript-eslint/max-params": ["warn", { "max": 5 }],
87
- "@typescript-eslint/no-confusing-void-expression": ["error", { "ignoreArrowShorthand": true, "ignoreVoidOperator": true }],
87
+ "@typescript-eslint/no-confusing-void-expression": ["warn", { "ignoreArrowShorthand": true, "ignoreVoidOperator": true }],
88
88
  "@typescript-eslint/no-empty-interface": ["warn", { "allowSingleExtends": true }],
89
89
  "@typescript-eslint/no-explicit-any": ["off"],
90
90
  "@typescript-eslint/no-inferrable-types": ["warn", { "ignoreParameters": true, "ignoreProperties": true }],
91
- "@typescript-eslint/no-invalid-void-type": ["error", { "allowInGenericTypeArguments": true }],
92
- "@typescript-eslint/no-magic-numbers": ["error", { "ignoreEnums": true, "ignoreNumericLiteralTypes": true, "ignoreReadonlyClassProperties": true, "ignoreArrayIndexes": true, "ignoreTypeIndexes": true, "ignore": [0, 1, 2, 4, 8, 16, 32, 64, 128, 192, 255, 256, 512, 1024, 2048, 4096, 8192] }],
91
+ "@typescript-eslint/no-invalid-void-type": ["warn", { "allowInGenericTypeArguments": true }],
92
+ "@typescript-eslint/no-magic-numbers": ["warn", { "ignoreEnums": true, "ignoreNumericLiteralTypes": true, "ignoreReadonlyClassProperties": true, "ignoreArrayIndexes": true, "ignoreTypeIndexes": true, "ignore": [0, 1, 2, 4, 8, 16, 32, 64, 128, 192, 255, 256, 512, 1024, 2048, 4096, 8192] }],
93
93
  "@typescript-eslint/no-restricted-imports": ["warn"],
94
- "@typescript-eslint/no-unnecessary-condition": ["error", { "allowConstantLoopConditions": true }],
94
+ "@typescript-eslint/no-unnecessary-condition": ["warn", { "allowConstantLoopConditions": true }],
95
95
  "@typescript-eslint/no-unsafe-assignment": ["off"],
96
96
  "@typescript-eslint/no-unused-vars": ["warn", { "varsIgnorePattern": "^_", "argsIgnorePattern": "^_" }],
97
97
  "@typescript-eslint/no-use-before-define": ["off"],
98
98
  "@typescript-eslint/prefer-destructuring": ["off"],
99
- "@typescript-eslint/restrict-template-expressions": ["error", { "allowNumber": true, "allowBoolean": true, "allowNullish": true }],
99
+ "@typescript-eslint/restrict-template-expressions": ["warn", { "allowNumber": true, "allowBoolean": true, "allowNullish": true }],
100
100
  "@typescript-eslint/sort-type-constituents": ["off"],
101
101
  "@typescript-eslint/method-signature-style": ["off"],
102
102
 
@@ -105,7 +105,7 @@
105
105
  "@typescript-eslint/prefer-readonly-parameter-types": ["off"],
106
106
  "@typescript-eslint/explicit-module-boundary-types": ["off"],
107
107
 
108
- "@stylistic/brace-style": ["error", "stroustrup", { "allowSingleLine": true }],
108
+ "@stylistic/brace-style": ["warn", "stroustrup", { "allowSingleLine": true }],
109
109
  "@stylistic/explicit-module-boundary-types": ["off"],
110
110
  "@stylistic/newline-per-chained-call": ["off"],
111
111
  "@stylistic/no-extra-parens": ["off"],
@@ -121,41 +121,41 @@
121
121
 
122
122
  "import/consistent-type-specifier-style": ["off", "prefer-inline"],
123
123
  "import/newline-after-import": ["warn"],
124
- "import/no-absolute-path": ["error"],
125
- "import/no-anonymous-default-export": ["error"],
124
+ "import/no-absolute-path": ["warn"],
125
+ "import/no-anonymous-default-export": ["warn"],
126
126
  "import/no-cycle": ["off", { "ignoreExternal": true }],
127
127
  "import/no-duplicates": ["warn", { "prefer-inline": true }],
128
- "import/no-empty-named-blocks": ["error"],
128
+ "import/no-empty-named-blocks": ["warn"],
129
129
  "import/no-extraneous-dependencies": ["off", { "devDependencies": false, "includeTypes": true }],
130
- "import/no-mutable-exports": ["error"],
131
- "import/no-named-default": ["error"],
132
- "import/no-nodejs-modules": ["error"],
133
- "import/no-self-import": ["error"],
134
- "import/no-unassigned-import": ["error"],
130
+ "import/no-mutable-exports": ["warn"],
131
+ "import/no-named-default": ["warn"],
132
+ "import/no-nodejs-modules": ["warn"],
133
+ "import/no-self-import": ["warn"],
134
+ "import/no-unassigned-import": ["warn"],
135
135
  "import/no-useless-path-segments": ["warn"],
136
136
 
137
137
  /** misc */
138
138
  "@stylistic/lines-around-comment": ["warn", { "allowClassStart": true, "allowTypeStart": true }],
139
- "@stylistic/array-bracket-newline": ["error", "consistent"],
140
- "@stylistic/array-element-newline": ["error", "consistent"],
141
- "@stylistic/dot-location": ["error", "property"],
139
+ "@stylistic/array-bracket-newline": ["warn", "consistent"],
140
+ "@stylistic/array-element-newline": ["warn", "consistent"],
141
+ "@stylistic/dot-location": ["warn", "property"],
142
142
  "@stylistic/function-call-argument-newline": ["warn", "consistent"],
143
143
  "@stylistic/function-paren-newline": ["warn", "consistent"],
144
- "@stylistic/linebreak-style": ["error", "unix"],
144
+ "@stylistic/linebreak-style": ["warn", "unix"],
145
145
  "@stylistic/lines-between-class-members": ["warn", "always", { "exceptAfterSingleLine": true }],
146
146
  "@stylistic/object-property-newline": ["warn", { "allowAllPropertiesOnSameLine": true }],
147
147
  "@stylistic/operator-linebreak": ["warn", "before"],
148
- "@stylistic/padded-blocks": ["error", "never"],
149
- "@stylistic/quote-props": ["error", "consistent-as-needed"],
148
+ "@stylistic/padded-blocks": ["warn", "never"],
149
+ "@stylistic/quote-props": ["warn", "consistent-as-needed"],
150
150
  "@stylistic/quotes": ["warn", "single"],
151
- "@stylistic/semi": ["error", "always"],
152
- "@stylistic/multiline-ternary": ["error", "always-multiline"],
151
+ "@stylistic/semi": ["warn", "always"],
152
+ "@stylistic/multiline-ternary": ["warn", "always-multiline"],
153
153
  "@stylistic/generator-star-spacing": ["warn", { "before": false, "after": true }],
154
- "@stylistic/indent": ["warn", 2],
154
+ "@stylistic/indent": ["off"],
155
155
  "@stylistic/max-len": ["off"],
156
156
  "@stylistic/object-curly-spacing": ["warn", "always"],
157
157
 
158
- "@stylistic/member-delimiter-style": ["error", {
158
+ "@stylistic/member-delimiter-style": ["warn", {
159
159
  "multiline": {
160
160
  "delimiter": "comma",
161
161
  "requireLast": false
@@ -1,13 +1,11 @@
1
1
  import 'urlpattern-polyfill';
2
2
  import type { HttpServerRequestContext } from '../../http/server/http-server.js';
3
- import type { HttpServerRequest } from '../../http/server/index.js';
4
- import { HttpServerResponse } from '../../http/server/index.js';
5
- import type { Resolvable } from '../../injector/index.js';
6
- import { resolveArgumentType } from '../../injector/index.js';
3
+ import { HttpServerResponse, type HttpServerRequest } from '../../http/server/index.js';
4
+ import { resolveArgumentType, type Resolvable } from '../../injector/index.js';
7
5
  import { Logger } from '../../logger/index.js';
8
6
  import type { Type } from '../../types.js';
9
- import type { AsyncMiddleware, AsyncMiddlewareNext } from '../../utils/middleware.js';
10
- import type { ApiController, ApiDefinition, ApiEndpointDefinition, ApiEndpointMethod, ApiEndpointServerImplementation } from '../types.js';
7
+ import { type AsyncMiddleware, type AsyncMiddlewareNext } from '../../utils/middleware.js';
8
+ import { type ApiController, type ApiDefinition, type ApiEndpointDefinition, type ApiEndpointMethod, type ApiEndpointServerImplementation } from '../types.js';
11
9
  import { ApiRequestTokenProvider } from './api-request-token.provider.js';
12
10
  import type { CorsMiddlewareOptions } from './middlewares/cors.middleware.js';
13
11
  export type ApiGatewayMiddlewareContext = {
package/function/log.d.ts CHANGED
@@ -1,7 +1,8 @@
1
1
  import type { Logger } from '../logger/logger.js';
2
2
  export type WrapLogOptions = {
3
3
  fnName?: string;
4
+ logResult?: boolean;
4
5
  logger?: Logger;
5
6
  trace?: boolean;
6
7
  };
7
- export declare function wrapLog(fn: Function, { fnName, logger, trace }?: WrapLogOptions): Function;
8
+ export declare function wrapLog(fn: Function, { fnName, logResult, logger, trace }?: WrapLogOptions): Function;
package/function/log.js CHANGED
@@ -1,23 +1,28 @@
1
1
  /* eslint-disable @typescript-eslint/ban-types */
2
2
  import { isArray, isPrimitive, isString } from '../utils/type-guards.js';
3
3
  import { typeOf } from '../utils/type-of.js';
4
- export function wrapLog(fn, { fnName = fn.name, logger, trace = false } = {}) {
4
+ export function wrapLog(fn, { fnName = fn.name, logResult = true, logger, trace = false } = {}) {
5
5
  const log = logger?.trace.bind(logger) ?? console.log.bind(console); // eslint-disable-line no-console
6
6
  const wrapped = {
7
7
  [fnName](...args) {
8
- const argString = args.map((arg) => stringifyArg(arg)).join(', ');
8
+ const argString = args.map((arg) => stringifyValue(arg)).join(', ');
9
9
  log(`[call: ${fnName}(${argString})]`);
10
10
  if (trace) {
11
11
  console.trace();
12
12
  }
13
- return Reflect.apply(fn, this, args);
13
+ const result = Reflect.apply(fn, this, args);
14
+ if (logResult) {
15
+ const resultString = stringifyValue(result);
16
+ log(`[return: ${fnName} => ${resultString}]`);
17
+ }
18
+ return result;
14
19
  }
15
20
  };
16
21
  return wrapped[fnName];
17
22
  }
18
- function stringifyArg(arg, depth = 1) {
23
+ function stringifyValue(arg, depth = 1) {
19
24
  if (isArray(arg) && (depth > 0)) {
20
- const argString = arg.map((innerArg) => stringifyArg(innerArg, depth - 1)).join(', ');
25
+ const argString = arg.map((innerArg) => stringifyValue(innerArg, depth - 1)).join(', ');
21
26
  return `[${argString}]`;
22
27
  }
23
28
  return isPrimitive(arg) ? isString(arg) ? `"${arg}"` : String(arg) : typeOf(arg);
@@ -1,4 +1,4 @@
1
- import type { Decorator } from '../reflection/index.js';
1
+ import { type Decorator } from '../reflection/index.js';
2
2
  import type { Constructor, OneOrMany, Record, Simplify, TypedOmit } from '../types.js';
3
3
  import type { Provider } from './provider.js';
4
4
  import type { InjectionToken } from './token.js';
@@ -6,9 +6,9 @@ import type { InjectMetadata } from './type-info.js';
6
6
  import type { ArgumentProvider, ForwardRefInjectionToken, Mapper, RegistrationOptions } from './types.js';
7
7
  export type InjectDecorator = Decorator<'accessor' | 'constructorParameter'>;
8
8
  export type InjectableOptions<T, A, C extends Record = Record> = RegistrationOptions<T, A, C> & {
9
- /** aliases (tokens) for the class. Useful for example for circular dependencies when you can't use the class itself as a token */
9
+ /** Aliases (tokens) for the class. Useful for example for circular dependencies when you can't use the class itself as a token */
10
10
  alias?: OneOrMany<InjectionToken>;
11
- /** custom provider. Useful for example if initialization is required */
11
+ /** Custom provider. Useful for example if initialization is required */
12
12
  provider?: Provider<T, A, C>;
13
13
  };
14
14
  export type InjectableOptionsWithoutLifecycle<T, A> = Simplify<TypedOmit<InjectableOptions<T, A>, 'lifecycle'>>;
@@ -24,58 +24,58 @@ export declare function ReplaceClass<T>(constructor: Constructor<T>): ClassDecor
24
24
  */
25
25
  export declare function Injectable<T = any, A = any, C extends Record = Record>(options?: InjectableOptions<T, A, C>): ClassDecorator;
26
26
  /**
27
- * registers the class in the global container with singleton lifecycle. Decorated class is not modified in any way
27
+ * Registers the class in the global container with singleton lifecycle. Decorated class is not modified in any way
28
28
  * @param options registration options
29
29
  */
30
30
  export declare function Singleton<T = any, A = any>(options?: InjectableOptionsWithoutLifecycle<T, A>): ClassDecorator;
31
31
  /**
32
- * registers the class in the global container with scoped lifecycle. Decorated class is not modified in any way
32
+ * Registers the class in the global container with scoped lifecycle. Decorated class is not modified in any way
33
33
  * @param options registration options
34
34
  */
35
35
  export declare function Scoped<T = any, A = any>(lifecycle: 'resolution' | 'injector', options?: InjectableOptionsWithoutLifecycle<T, A>): ClassDecorator;
36
36
  /**
37
- * sets the token used to resolve the parameter
37
+ * Sets the token used to resolve the parameter
38
38
  * @param token token used for resolving
39
39
  * @param argument resolve argument
40
40
  * @param mapperOrKey map the resolved value. If {@link PropertyKey} is provided, that property of the resolved value will be injected
41
41
  */
42
42
  export declare function Inject<T, A>(token?: InjectionToken<T, A>, argument?: A, mapperOrKey?: Mapper<T> | keyof T): InjectDecorator;
43
43
  /**
44
- * sets the token used to resolve the parameter. Resolves all providers
44
+ * Sets the token used to resolve the parameter. Resolves all providers
45
45
  * @param token token used for resolving
46
46
  * @param argument resolve argument
47
47
  * @param mapperOrKey map the resolved value. If {@link PropertyKey} is provided, that property of the resolved value will be injected
48
48
  */
49
49
  export declare function InjectAll<T, A>(token?: InjectionToken<T, A>, argument?: A, mapperOrKey?: Mapper<T> | keyof T): InjectDecorator;
50
50
  /**
51
- * sets the argument used for resolving the parameter
51
+ * Sets the argument used for resolving the parameter
52
52
  * @param argument
53
53
  */
54
54
  export declare function ResolveArg<T>(argument: T): InjectDecorator;
55
55
  /**
56
- * sets the argument provider used for resolving the parameter
56
+ * Sets the argument provider used for resolving the parameter
57
57
  * @param argumentProvider
58
58
  */
59
59
  export declare function ResolveArgProvider<T>(argumentProvider: ArgumentProvider<T>): InjectDecorator;
60
60
  /**
61
- * injects the argument used for resolving the class instead of resolving the parameter
61
+ * Injects the argument used for resolving the class instead of resolving the parameter
62
62
  * @param argument
63
63
  * @param mapperOrKey map the resolved value. If {@link PropertyKey} is provided, that property of the resolved value will be injected
64
64
  */
65
65
  export declare function InjectArg<T>(mapperOrKey?: Mapper<T> | keyof T): InjectDecorator;
66
66
  /**
67
- * sets the argument used for resolving the decorated parameter to the the argument provided for parent resolve
67
+ * Sets the argument used for resolving the decorated parameter to the the argument provided for parent resolve
68
68
  * @param mapper map the argument (for example to select a property instead of forwarding the whole object)
69
69
  */
70
70
  export declare function ForwardArg(): InjectDecorator;
71
71
  export declare function ForwardArg<T, U>(mapper: Mapper<T, U>): InjectDecorator;
72
72
  /**
73
- * marks the argument as optional
73
+ * Marks the argument as optional
74
74
  * @param argument
75
75
  */
76
76
  export declare function Optional(): InjectDecorator;
77
77
  /**
78
- * resolve using ForwardRef to handle circular dependencies. Resolve logic derefs all ForwardRefs which are direct properties of resolved instances automatically
78
+ * Resolve using ForwardRef to handle circular dependencies. Resolve logic derefs all ForwardRefs which are direct properties of resolved instances automatically
79
79
  * @param token token to resolve
80
80
  * @param argument resolve argument
81
81
  */
@@ -34,21 +34,21 @@ export function Injectable(options = {}) {
34
34
  });
35
35
  }
36
36
  /**
37
- * registers the class in the global container with singleton lifecycle. Decorated class is not modified in any way
37
+ * Registers the class in the global container with singleton lifecycle. Decorated class is not modified in any way
38
38
  * @param options registration options
39
39
  */
40
40
  export function Singleton(options = {}) {
41
41
  return Injectable({ ...options, lifecycle: 'singleton' });
42
42
  }
43
43
  /**
44
- * registers the class in the global container with scoped lifecycle. Decorated class is not modified in any way
44
+ * Registers the class in the global container with scoped lifecycle. Decorated class is not modified in any way
45
45
  * @param options registration options
46
46
  */
47
47
  export function Scoped(lifecycle, options = {}) {
48
48
  return Injectable({ ...options, lifecycle });
49
49
  }
50
50
  /**
51
- * sets the token used to resolve the parameter
51
+ * Sets the token used to resolve the parameter
52
52
  * @param token token used for resolving
53
53
  * @param argument resolve argument
54
54
  * @param mapperOrKey map the resolved value. If {@link PropertyKey} is provided, that property of the resolved value will be injected
@@ -67,7 +67,7 @@ export function Inject(token, argument, mapperOrKey) {
67
67
  return createInjectDecorator(injectMetadata);
68
68
  }
69
69
  /**
70
- * sets the token used to resolve the parameter. Resolves all providers
70
+ * Sets the token used to resolve the parameter. Resolves all providers
71
71
  * @param token token used for resolving
72
72
  * @param argument resolve argument
73
73
  * @param mapperOrKey map the resolved value. If {@link PropertyKey} is provided, that property of the resolved value will be injected
@@ -86,21 +86,21 @@ export function InjectAll(token, argument, mapperOrKey) {
86
86
  return createInjectDecorator(injectMetadata);
87
87
  }
88
88
  /**
89
- * sets the argument used for resolving the parameter
89
+ * Sets the argument used for resolving the parameter
90
90
  * @param argument
91
91
  */
92
92
  export function ResolveArg(argument) {
93
93
  return ResolveArgProvider(() => argument);
94
94
  }
95
95
  /**
96
- * sets the argument provider used for resolving the parameter
96
+ * Sets the argument provider used for resolving the parameter
97
97
  * @param argumentProvider
98
98
  */
99
99
  export function ResolveArgProvider(argumentProvider) {
100
100
  return createInjectDecorator({ resolveArgumentProvider: argumentProvider });
101
101
  }
102
102
  /**
103
- * injects the argument used for resolving the class instead of resolving the parameter
103
+ * Injects the argument used for resolving the class instead of resolving the parameter
104
104
  * @param argument
105
105
  * @param mapperOrKey map the resolved value. If {@link PropertyKey} is provided, that property of the resolved value will be injected
106
106
  */
@@ -117,14 +117,14 @@ export function ForwardArg(mapper = (value) => value) {
117
117
  return createInjectDecorator({ forwardArgumentMapper: mapper });
118
118
  }
119
119
  /**
120
- * marks the argument as optional
120
+ * Marks the argument as optional
121
121
  * @param argument
122
122
  */
123
123
  export function Optional() {
124
124
  return createInjectDecorator({ optional: true });
125
125
  }
126
126
  /**
127
- * resolve using ForwardRef to handle circular dependencies. Resolve logic derefs all ForwardRefs which are direct properties of resolved instances automatically
127
+ * Resolve using ForwardRef to handle circular dependencies. Resolve logic derefs all ForwardRefs which are direct properties of resolved instances automatically
128
128
  * @param token token to resolve
129
129
  * @param argument resolve argument
130
130
  */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tstdl/base",
3
- "version": "0.90.59",
3
+ "version": "0.90.61",
4
4
  "author": "Patrick Hein",
5
5
  "publishConfig": {
6
6
  "access": "public"
@@ -109,11 +109,11 @@
109
109
  "luxon": "^3.4",
110
110
  "reflect-metadata": "^0.2",
111
111
  "rxjs": "^7.8",
112
- "type-fest": "4.10"
112
+ "type-fest": "4.14"
113
113
  },
114
114
  "devDependencies": {
115
115
  "@mxssfd/typedoc-theme": "1.1",
116
- "@stylistic/eslint-plugin": "1.6",
116
+ "@stylistic/eslint-plugin": "1.7",
117
117
  "@types/chroma-js": "2.4",
118
118
  "@types/koa__router": "12.0",
119
119
  "@types/luxon": "3.4",
@@ -129,8 +129,8 @@
129
129
  "tsc-alias": "1.8",
130
130
  "typedoc": "0.25",
131
131
  "typedoc-plugin-missing-exports": "2.2",
132
- "typescript": "5.3",
133
- "typescript-eslint": "7.1"
132
+ "typescript": "5.4",
133
+ "typescript-eslint": "7.3"
134
134
  },
135
135
  "peerDependencies": {
136
136
  "@elastic/elasticsearch": "^8.12",
@@ -145,12 +145,12 @@
145
145
  "koa": "^2.15",
146
146
  "minio": "^7.1",
147
147
  "mjml": "^4.15",
148
- "mongodb": "^6.4",
148
+ "mongodb": "^6.5",
149
149
  "nodemailer": "^6.9",
150
150
  "playwright": "^1.42",
151
- "preact": "^10.19",
151
+ "preact": "^10.20",
152
152
  "preact-render-to-string": "^6.4",
153
- "undici": "^6.6",
153
+ "undici": "^6.10",
154
154
  "urlpattern-polyfill": "^10.0"
155
155
  },
156
156
  "peerDependenciesMeta": {
@@ -1,2 +1,2 @@
1
- import type { Signal } from './api.js';
1
+ import { type Signal } from './api.js';
2
2
  export declare function defer<T>(signalFactory: () => Signal<T>): Signal<T>;
@@ -21,19 +21,14 @@ export declare abstract class EffectScheduler {
21
21
  * It is an error to attempt to execute any effects synchronously during a scheduling operation.
22
22
  */
23
23
  abstract scheduleEffect(e: SchedulableEffect): void;
24
- }
25
- /**
26
- * Interface to an `EffectScheduler` capable of running scheduled effects synchronously.
27
- */
28
- export interface FlushableEffectRunner {
29
24
  /**
30
25
  * Run any scheduled effects.
31
26
  */
32
- flush(): void;
27
+ abstract flush(): void;
33
28
  }
34
- export declare class TstdlEffectScheduler implements EffectScheduler, FlushableEffectRunner {
29
+ export declare class TstdlEffectScheduler implements EffectScheduler {
35
30
  private readonly queue;
36
- private pendingFlush;
31
+ private hasPendingFlush;
37
32
  scheduleEffect(effect: SchedulableEffect): void;
38
33
  flush(): void;
39
34
  }
@@ -15,13 +15,16 @@ export class EffectScheduler {
15
15
  }
16
16
  export class TstdlEffectScheduler {
17
17
  queue = new Set();
18
- pendingFlush = false;
18
+ hasPendingFlush = false;
19
19
  scheduleEffect(effect) {
20
+ if (this.queue.has(effect)) {
21
+ return;
22
+ }
20
23
  this.queue.add(effect);
21
- if (!this.pendingFlush) {
22
- this.pendingFlush = true;
24
+ if (!this.hasPendingFlush) {
25
+ this.hasPendingFlush = true;
23
26
  queueMicrotask(() => {
24
- this.pendingFlush = false;
27
+ this.hasPendingFlush = false;
25
28
  this.flush();
26
29
  });
27
30
  }
@@ -44,7 +44,7 @@ export interface WritableSignal<T> extends Signal<T> {
44
44
  update(updateFn: (value: T) => T): void;
45
45
  /**
46
46
  * Returns a readonly version of this signal. Readonly signals can be accessed to read their value
47
- * but can't be changed using set, update or mutate methods. The readonly signals do _not_ have
47
+ * but can't be changed using set or update methods. The readonly signals do _not_ have
48
48
  * any built-in mechanism that would prevent deep-mutation of their value.
49
49
  */
50
50
  asReadonly(): Signal<T>;
@@ -10,7 +10,7 @@ export type ForwardRef<T extends object = object> = T & {
10
10
  [isForwardRef]: true;
11
11
  };
12
12
  export declare const ForwardRef: {
13
- create<T extends object>(options?: ForwardRefOptions<T> | undefined): ForwardRef<T>;
13
+ create<T extends object>(options?: ForwardRefOptions<T>): ForwardRef<T>;
14
14
  isForwardRef<T_1 extends object = object>(value: any): value is ForwardRef<T_1>;
15
15
  hasRef<T_2 extends object>(forwardRef: T_2 | ForwardRef<T_2>): boolean;
16
16
  deref<T_3 extends object>(forwardRef: T_3 | ForwardRef<T_3>): T_3;