alepha 0.20.3 → 0.20.4
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/api/audits/index.d.ts.map +1 -1
- package/dist/api/files/index.d.ts.map +1 -1
- package/dist/api/jobs/index.d.ts +14 -14
- package/dist/api/jobs/index.d.ts.map +1 -1
- package/dist/api/keys/index.d.ts +4 -4
- package/dist/api/organizations/index.d.ts.map +1 -1
- package/dist/api/parameters/index.d.ts +8 -3
- package/dist/api/parameters/index.d.ts.map +1 -1
- package/dist/api/parameters/index.js +20 -4
- package/dist/api/parameters/index.js.map +1 -1
- package/dist/api/payments/index.d.ts.map +1 -1
- package/dist/api/users/index.browser.js +6 -0
- package/dist/api/users/index.browser.js.map +1 -1
- package/dist/api/users/index.d.ts +5037 -139
- package/dist/api/users/index.d.ts.map +1 -1
- package/dist/api/users/index.js +58 -10
- package/dist/api/users/index.js.map +1 -1
- package/dist/bucket/index.d.ts +77 -107
- package/dist/bucket/index.d.ts.map +1 -1
- package/dist/bucket/index.js +148 -4
- package/dist/bucket/index.js.map +1 -1
- package/dist/bucket/index.workerd.js +7 -1
- package/dist/bucket/index.workerd.js.map +1 -1
- package/dist/cache/core/index.d.ts +26 -0
- package/dist/cache/core/index.d.ts.map +1 -1
- package/dist/cache/core/index.js +11 -1
- package/dist/cache/core/index.js.map +1 -1
- package/dist/cache/core/index.workerd.js +11 -1
- package/dist/cache/core/index.workerd.js.map +1 -1
- package/dist/cli/config/index.d.ts +7 -5
- package/dist/cli/config/index.d.ts.map +1 -1
- package/dist/cli/config/index.js +2 -3
- package/dist/cli/config/index.js.map +1 -1
- package/dist/cli/core/index.d.ts +420 -13
- package/dist/cli/core/index.d.ts.map +1 -1
- package/dist/cli/core/index.js +22 -511
- package/dist/cli/core/index.js.map +1 -1
- package/dist/cli/devtools/index.d.ts +4 -8
- package/dist/cli/devtools/index.d.ts.map +1 -1
- package/dist/cli/devtools/index.js +13 -15
- package/dist/cli/devtools/index.js.map +1 -1
- package/dist/cli/platform/index.d.ts +10 -13
- package/dist/cli/platform/index.d.ts.map +1 -1
- package/dist/cli/platform/index.js +18 -15
- package/dist/cli/platform/index.js.map +1 -1
- package/dist/cli/vendor/index.d.ts +10 -13
- package/dist/cli/vendor/index.d.ts.map +1 -1
- package/dist/cli/vendor/index.js +16 -13
- package/dist/cli/vendor/index.js.map +1 -1
- package/dist/core/index.browser.js +27 -3
- package/dist/core/index.browser.js.map +1 -1
- package/dist/core/index.d.ts +6 -3
- package/dist/core/index.d.ts.map +1 -1
- package/dist/core/index.js +27 -3
- package/dist/core/index.js.map +1 -1
- package/dist/core/index.native.js +27 -3
- package/dist/core/index.native.js.map +1 -1
- package/dist/core/index.workerd.js +27 -3
- package/dist/core/index.workerd.js.map +1 -1
- package/dist/datetime/index.d.ts +69 -10
- package/dist/datetime/index.d.ts.map +1 -1
- package/dist/datetime/index.js +135 -13
- package/dist/datetime/index.js.map +1 -1
- package/dist/email/smtp/index.js +10636 -2
- package/dist/email/smtp/index.js.map +1 -1
- package/dist/fake/index.d.ts +8085 -4
- package/dist/fake/index.d.ts.map +1 -1
- package/dist/fake/index.js +33554 -3
- package/dist/fake/index.js.map +1 -1
- package/dist/lock/core/index.d.ts +30 -2
- package/dist/lock/core/index.d.ts.map +1 -1
- package/dist/lock/core/index.js +35 -12
- package/dist/lock/core/index.js.map +1 -1
- package/dist/mcp/index.d.ts +238 -31
- package/dist/mcp/index.d.ts.map +1 -1
- package/dist/mcp/index.js +198 -71
- package/dist/mcp/index.js.map +1 -1
- package/dist/orm/core/index.browser.js +1 -1
- package/dist/orm/core/index.browser.js.map +1 -1
- package/dist/orm/core/index.bun.js +4 -3
- package/dist/orm/core/index.bun.js.map +1 -1
- package/dist/orm/core/index.d.ts +4877 -9
- package/dist/orm/core/index.d.ts.map +1 -1
- package/dist/orm/core/index.js +4 -3
- package/dist/orm/core/index.js.map +1 -1
- package/dist/orm/postgres/index.d.ts +608 -1
- package/dist/orm/postgres/index.d.ts.map +1 -1
- package/dist/react/core/index.d.ts +102 -1
- package/dist/react/core/index.d.ts.map +1 -1
- package/dist/react/core/index.js +65 -1
- package/dist/react/core/index.js.map +1 -1
- package/dist/react/form/index.d.ts +6 -0
- package/dist/react/form/index.d.ts.map +1 -1
- package/dist/react/form/index.js +7 -7
- package/dist/react/form/index.js.map +1 -1
- package/dist/react/i18n/index.d.ts +7 -1
- package/dist/react/i18n/index.d.ts.map +1 -1
- package/dist/react/i18n/index.js +6 -0
- package/dist/react/i18n/index.js.map +1 -1
- package/dist/react/router/index.browser.js +20 -2
- package/dist/react/router/index.browser.js.map +1 -1
- package/dist/react/router/index.d.ts +36 -4
- package/dist/react/router/index.d.ts.map +1 -1
- package/dist/react/router/index.js +20 -2
- package/dist/react/router/index.js.map +1 -1
- package/dist/react/testing/chunk-6Ep1yQYe.js +16 -0
- package/dist/react/testing/index.d.ts +411 -1
- package/dist/react/testing/index.d.ts.map +1 -1
- package/dist/react/testing/index.js +12293 -13
- package/dist/react/testing/index.js.map +1 -1
- package/dist/react/ui/index.d.ts +195 -1
- package/dist/react/ui/index.d.ts.map +1 -1
- package/dist/react/ui/index.js +61 -1
- package/dist/react/ui/index.js.map +1 -1
- package/dist/scheduler/index.d.ts +84 -3
- package/dist/scheduler/index.d.ts.map +1 -1
- package/dist/scheduler/index.js +390 -1
- package/dist/scheduler/index.js.map +1 -1
- package/dist/scheduler/index.workerd.js +390 -1
- package/dist/scheduler/index.workerd.js.map +1 -1
- package/dist/security/index.d.ts +325 -2
- package/dist/security/index.d.ts.map +1 -1
- package/dist/security/index.js +1361 -2
- package/dist/security/index.js.map +1 -1
- package/dist/server/auth/index.d.ts +1054 -1
- package/dist/server/auth/index.d.ts.map +1 -1
- package/dist/server/auth/index.js +1223 -1
- package/dist/server/auth/index.js.map +1 -1
- package/dist/server/core/index.browser.js +10 -3
- package/dist/server/core/index.browser.js.map +1 -1
- package/dist/server/core/index.d.ts.map +1 -1
- package/dist/server/core/index.js +28 -5
- package/dist/server/core/index.js.map +1 -1
- package/dist/server/metrics/index.d.ts +514 -1
- package/dist/server/metrics/index.d.ts.map +1 -1
- package/dist/server/metrics/index.js +4374 -4
- package/dist/server/metrics/index.js.map +1 -1
- package/dist/server/swagger/index.d.ts.map +1 -1
- package/dist/server/swagger/index.js +3 -4
- package/dist/server/swagger/index.js.map +1 -1
- package/dist/websocket/index.browser.js +11 -5
- package/dist/websocket/index.browser.js.map +1 -1
- package/dist/websocket/index.d.ts +3 -1
- package/dist/websocket/index.d.ts.map +1 -1
- package/dist/websocket/index.js +21 -6
- package/dist/websocket/index.js.map +1 -1
- package/package.json +671 -263
- package/src/api/parameters/services/ParameterProvider.ts +21 -4
- package/src/api/users/__tests__/SessionService.spec.ts +99 -0
- package/src/api/users/__tests__/UserJobs.spec.ts +67 -0
- package/src/api/users/atoms/realmAuthSettingsAtom.ts +15 -0
- package/src/api/users/entities/sessions.ts +6 -0
- package/src/api/users/jobs/UserJobs.ts +44 -17
- package/src/api/users/providers/RealmProvider.ts +4 -0
- package/src/api/users/services/SessionService.ts +27 -0
- package/src/bucket/__tests__/NodeS3BucketProvider.spec.ts +74 -0
- package/src/bucket/index.ts +19 -2
- package/src/bucket/primitives/$bucket.ts +9 -1
- package/src/bucket/providers/CloudflareR2Provider.ts +2 -137
- package/src/bucket/providers/NodeS3BucketProvider.ts +218 -0
- package/src/cache/core/index.ts +29 -0
- package/src/cache/core/primitives/$cache.ts +14 -1
- package/src/cli/config/defineConfig.ts +13 -15
- package/src/cli/core/__tests__/init.spec.ts +6 -7
- package/src/cli/core/services/ProjectScaffolder.ts +18 -14
- package/src/cli/core/tasks/BuildCloudflareTask.ts +5 -0
- package/src/cli/core/templates/agentMd.ts +2 -10
- package/src/cli/core/templates/saasAdminLayoutTsx.ts +3 -3
- package/src/cli/devtools/index.ts +12 -26
- package/src/cli/platform/index.ts +15 -24
- package/src/cli/vendor/atoms/vendorOptions.ts +1 -1
- package/src/cli/vendor/index.ts +14 -23
- package/src/core/Alepha.ts +11 -1
- package/src/core/helpers/ref.ts +18 -0
- package/src/core/index.shared.ts +1 -0
- package/src/core/providers/SchemaValidator.ts +9 -1
- package/src/core/providers/TypeProvider.ts +1 -2
- package/src/datetime/REFACTORING.md +118 -0
- package/src/datetime/providers/DateTimeProvider.ts +203 -24
- package/src/lock/core/index.ts +31 -0
- package/src/lock/core/primitives/$lock.ts +14 -1
- package/src/mcp/__tests__/jsonrpc.spec.ts +1 -1
- package/src/mcp/helpers/jsonrpc.ts +26 -1
- package/src/mcp/index.ts +10 -5
- package/src/mcp/interfaces/McpTypes.ts +83 -6
- package/src/mcp/primitives/$prompt.ts +18 -1
- package/src/mcp/primitives/$resource.ts +18 -1
- package/src/mcp/primitives/$tool.ts +83 -7
- package/src/mcp/providers/McpServerProvider.ts +74 -16
- package/src/mcp/transports/StreamableHttpMcpTransport.ts +226 -0
- package/src/orm/REFACTORING.md +330 -0
- package/src/orm/core/primitives/$transactional.ts +11 -0
- package/src/orm/core/schemas/updateSchema.ts +1 -1
- package/src/orm/core/services/PgRelationManager.ts +4 -2
- package/src/react/core/__tests__/useQuery.browser.spec.tsx +86 -0
- package/src/react/core/hooks/useQuery.ts +153 -0
- package/src/react/core/index.ts +1 -0
- package/src/react/form/services/FormModel.ts +15 -6
- package/src/react/form/services/parseField.ts +8 -0
- package/src/react/i18n/providers/I18nProvider.ts +8 -2
- package/src/react/router/__tests__/$page.spec.tsx +0 -16
- package/src/react/router/__tests__/ssr.spec.tsx +339 -0
- package/src/react/router/primitives/$page.ts +28 -4
- package/src/react/router/providers/ReactPageProvider.ts +27 -9
- package/src/react/ui/atoms/uiThemeListAtom.ts +36 -0
- package/src/react/ui/index.ts +6 -0
- package/src/react/ui/services/SchemaControl.ts +209 -0
- package/src/security/primitives/$issuer.ts +6 -3
- package/src/server/core/__tests__/ServerRouterProvider-serializationError.spec.ts +75 -0
- package/src/server/core/__tests__/ServerRouterProvider-validationError.spec.ts +306 -0
- package/src/server/core/errors/ValidationError.ts +13 -1
- package/src/server/core/primitives/$action.ts +16 -5
- package/src/server/core/providers/ServerRouterProvider.ts +26 -4
- package/src/server/swagger/providers/ServerSwaggerProvider.ts +5 -7
- package/src/websocket/providers/NodeWebSocketServerProvider.ts +10 -4
- package/src/websocket/services/WebSocketClient.ts +11 -5
- package/src/mcp/transports/SseMcpTransport.ts +0 -182
package/dist/datetime/index.d.ts
CHANGED
|
@@ -1,13 +1,72 @@
|
|
|
1
1
|
import * as _$alepha from "alepha";
|
|
2
2
|
import { Alepha, KIND, Middleware, Primitive } from "alepha";
|
|
3
|
-
import dayjsDuration from "dayjs/plugin/duration.js";
|
|
4
|
-
import
|
|
3
|
+
import dayjsDuration, { DurationUnitType } from "dayjs/plugin/duration.js";
|
|
4
|
+
import { Dayjs, ManipulateType, OpUnitType, PluginFunc, QUnitType } from "dayjs";
|
|
5
5
|
|
|
6
6
|
//#region ../../src/datetime/providers/DateTimeProvider.d.ts
|
|
7
|
-
type
|
|
8
|
-
type
|
|
9
|
-
|
|
10
|
-
|
|
7
|
+
type DateTimeInput = string | number | Date | DateTime | Dayjs;
|
|
8
|
+
type DurationLike = number | Duration | [number, ManipulateType];
|
|
9
|
+
/**
|
|
10
|
+
* Immutable wrapper around the underlying date-time engine.
|
|
11
|
+
*
|
|
12
|
+
* Designed to isolate consumers from the engine in use (currently dayjs).
|
|
13
|
+
* Methods that produce a new value return a new `DateTime` instance.
|
|
14
|
+
*/
|
|
15
|
+
declare class DateTime {
|
|
16
|
+
protected readonly inner: Dayjs;
|
|
17
|
+
constructor(inner: Dayjs);
|
|
18
|
+
/**
|
|
19
|
+
* Add a duration to this date-time.
|
|
20
|
+
*/
|
|
21
|
+
add(amount: number, unit?: ManipulateType): DateTime;
|
|
22
|
+
add(duration: Duration): DateTime;
|
|
23
|
+
/**
|
|
24
|
+
* Subtract a duration from this date-time.
|
|
25
|
+
*/
|
|
26
|
+
subtract(amount: number, unit?: ManipulateType): DateTime;
|
|
27
|
+
subtract(duration: Duration): DateTime;
|
|
28
|
+
startOf(unit: OpUnitType): DateTime;
|
|
29
|
+
endOf(unit: OpUnitType): DateTime;
|
|
30
|
+
isAfter(other: DateTimeInput): boolean;
|
|
31
|
+
isBefore(other: DateTimeInput): boolean;
|
|
32
|
+
isSame(other: DateTimeInput, unit?: OpUnitType): boolean;
|
|
33
|
+
diff(other: DateTimeInput, unit?: QUnitType | OpUnitType): number;
|
|
34
|
+
tz(timezone: string): DateTime;
|
|
35
|
+
locale(lang: string): DateTime;
|
|
36
|
+
format(template?: string): string;
|
|
37
|
+
fromNow(withoutSuffix?: boolean): string;
|
|
38
|
+
toISOString(): string;
|
|
39
|
+
toDate(): Date;
|
|
40
|
+
valueOf(): number;
|
|
41
|
+
unix(): number;
|
|
42
|
+
toJSON(): string;
|
|
43
|
+
toString(): string;
|
|
44
|
+
/**
|
|
45
|
+
* Escape hatch for the underlying dayjs instance.
|
|
46
|
+
*
|
|
47
|
+
* Use sparingly — anything calling this becomes coupled to dayjs and
|
|
48
|
+
* will need to migrate when the engine is replaced.
|
|
49
|
+
*/
|
|
50
|
+
toDayjs(): Dayjs;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Immutable wrapper around the underlying duration engine.
|
|
54
|
+
*/
|
|
55
|
+
declare class Duration {
|
|
56
|
+
protected readonly inner: dayjsDuration.Duration;
|
|
57
|
+
constructor(inner: dayjsDuration.Duration);
|
|
58
|
+
asMilliseconds(): number;
|
|
59
|
+
asSeconds(): number;
|
|
60
|
+
asMinutes(): number;
|
|
61
|
+
asHours(): number;
|
|
62
|
+
asDays(): number;
|
|
63
|
+
as(unit: DurationUnitType): number;
|
|
64
|
+
toISOString(): string;
|
|
65
|
+
/**
|
|
66
|
+
* Escape hatch for the underlying dayjs duration.
|
|
67
|
+
*/
|
|
68
|
+
toDayjs(): dayjsDuration.Duration;
|
|
69
|
+
}
|
|
11
70
|
declare const isDateTime: (value: unknown) => value is DateTime;
|
|
12
71
|
declare class DateTimeProvider {
|
|
13
72
|
static PLUGINS: Array<PluginFunc<any>>;
|
|
@@ -23,15 +82,15 @@ declare class DateTimeProvider {
|
|
|
23
82
|
/**
|
|
24
83
|
* Create a new UTC DateTime instance.
|
|
25
84
|
*/
|
|
26
|
-
utc(date:
|
|
85
|
+
utc(date: DateTimeInput | null | undefined): DateTime;
|
|
27
86
|
/**
|
|
28
87
|
* Create a new DateTime instance.
|
|
29
88
|
*/
|
|
30
|
-
of(date:
|
|
89
|
+
of(date: DateTimeInput | null | undefined): DateTime;
|
|
31
90
|
/**
|
|
32
91
|
* Get the current date as a string.
|
|
33
92
|
*/
|
|
34
|
-
toISOString(date?:
|
|
93
|
+
toISOString(date?: DateTimeInput): string;
|
|
35
94
|
/**
|
|
36
95
|
* Get the current date.
|
|
37
96
|
*/
|
|
@@ -234,5 +293,5 @@ declare const $timeout: (duration: DurationLike) => Middleware;
|
|
|
234
293
|
*/
|
|
235
294
|
declare const AlephaDateTime: _$alepha.Service<_$alepha.Module>;
|
|
236
295
|
//#endregion
|
|
237
|
-
export { $debounce, $interval, $throttle, $timeout, AlephaDateTime, DateTime, DateTimeProvider, DebounceOptions, Duration, DurationLike, Interval, IntervalPrimitive, IntervalPrimitiveOptions, ThrottleOptions, Timeout,
|
|
296
|
+
export { $debounce, $interval, $throttle, $timeout, AlephaDateTime, DateTime, DateTimeInput, DateTimeProvider, DebounceOptions, Duration, DurationLike, type DurationUnitType, Interval, IntervalPrimitive, IntervalPrimitiveOptions, type ManipulateType, type OpUnitType, type QUnitType, ThrottleOptions, Timeout, isDateTime };
|
|
238
297
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","names":[],"sources":["../../src/datetime/providers/DateTimeProvider.ts","../../src/datetime/primitives/$debounce.ts","../../src/datetime/primitives/$interval.ts","../../src/datetime/primitives/$throttle.ts","../../src/datetime/primitives/$timeout.ts","../../src/datetime/index.ts"],"mappings":";;;;;;
|
|
1
|
+
{"version":3,"file":"index.d.ts","names":[],"sources":["../../src/datetime/providers/DateTimeProvider.ts","../../src/datetime/primitives/$debounce.ts","../../src/datetime/primitives/$interval.ts","../../src/datetime/primitives/$throttle.ts","../../src/datetime/primitives/$timeout.ts","../../src/datetime/index.ts"],"mappings":"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"}
|
package/dist/datetime/index.js
CHANGED
|
@@ -8,9 +8,125 @@ import "dayjs/locale/ar.js";
|
|
|
8
8
|
import "dayjs/locale/fr.js";
|
|
9
9
|
import DayjsApi from "dayjs";
|
|
10
10
|
//#region ../../src/datetime/providers/DateTimeProvider.ts
|
|
11
|
-
|
|
11
|
+
/**
|
|
12
|
+
* Immutable wrapper around the underlying date-time engine.
|
|
13
|
+
*
|
|
14
|
+
* Designed to isolate consumers from the engine in use (currently dayjs).
|
|
15
|
+
* Methods that produce a new value return a new `DateTime` instance.
|
|
16
|
+
*/
|
|
17
|
+
var DateTime = class DateTime {
|
|
18
|
+
inner;
|
|
19
|
+
constructor(inner) {
|
|
20
|
+
this.inner = inner;
|
|
21
|
+
}
|
|
22
|
+
add(amount, unit) {
|
|
23
|
+
if (amount instanceof Duration) return new DateTime(this.inner.add(amount.toDayjs()));
|
|
24
|
+
return new DateTime(this.inner.add(amount, unit));
|
|
25
|
+
}
|
|
26
|
+
subtract(amount, unit) {
|
|
27
|
+
if (amount instanceof Duration) return new DateTime(this.inner.subtract(amount.toDayjs()));
|
|
28
|
+
return new DateTime(this.inner.subtract(amount, unit));
|
|
29
|
+
}
|
|
30
|
+
startOf(unit) {
|
|
31
|
+
return new DateTime(this.inner.startOf(unit));
|
|
32
|
+
}
|
|
33
|
+
endOf(unit) {
|
|
34
|
+
return new DateTime(this.inner.endOf(unit));
|
|
35
|
+
}
|
|
36
|
+
isAfter(other) {
|
|
37
|
+
return this.inner.isAfter(toDayjs(other));
|
|
38
|
+
}
|
|
39
|
+
isBefore(other) {
|
|
40
|
+
return this.inner.isBefore(toDayjs(other));
|
|
41
|
+
}
|
|
42
|
+
isSame(other, unit) {
|
|
43
|
+
return this.inner.isSame(toDayjs(other), unit);
|
|
44
|
+
}
|
|
45
|
+
diff(other, unit) {
|
|
46
|
+
return this.inner.diff(toDayjs(other), unit);
|
|
47
|
+
}
|
|
48
|
+
tz(timezone) {
|
|
49
|
+
return new DateTime(this.inner.tz(timezone));
|
|
50
|
+
}
|
|
51
|
+
locale(lang) {
|
|
52
|
+
return new DateTime(this.inner.locale(lang));
|
|
53
|
+
}
|
|
54
|
+
format(template) {
|
|
55
|
+
return this.inner.format(template);
|
|
56
|
+
}
|
|
57
|
+
fromNow(withoutSuffix) {
|
|
58
|
+
return this.inner.fromNow(withoutSuffix);
|
|
59
|
+
}
|
|
60
|
+
toISOString() {
|
|
61
|
+
return this.inner.toISOString();
|
|
62
|
+
}
|
|
63
|
+
toDate() {
|
|
64
|
+
return this.inner.toDate();
|
|
65
|
+
}
|
|
66
|
+
valueOf() {
|
|
67
|
+
return this.inner.valueOf();
|
|
68
|
+
}
|
|
69
|
+
unix() {
|
|
70
|
+
return this.inner.unix();
|
|
71
|
+
}
|
|
72
|
+
toJSON() {
|
|
73
|
+
return this.inner.toISOString();
|
|
74
|
+
}
|
|
75
|
+
toString() {
|
|
76
|
+
return this.inner.toISOString();
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Escape hatch for the underlying dayjs instance.
|
|
80
|
+
*
|
|
81
|
+
* Use sparingly — anything calling this becomes coupled to dayjs and
|
|
82
|
+
* will need to migrate when the engine is replaced.
|
|
83
|
+
*/
|
|
84
|
+
toDayjs() {
|
|
85
|
+
return this.inner;
|
|
86
|
+
}
|
|
87
|
+
};
|
|
88
|
+
/**
|
|
89
|
+
* Immutable wrapper around the underlying duration engine.
|
|
90
|
+
*/
|
|
91
|
+
var Duration = class {
|
|
92
|
+
inner;
|
|
93
|
+
constructor(inner) {
|
|
94
|
+
this.inner = inner;
|
|
95
|
+
}
|
|
96
|
+
asMilliseconds() {
|
|
97
|
+
return this.inner.asMilliseconds();
|
|
98
|
+
}
|
|
99
|
+
asSeconds() {
|
|
100
|
+
return this.inner.asSeconds();
|
|
101
|
+
}
|
|
102
|
+
asMinutes() {
|
|
103
|
+
return this.inner.asMinutes();
|
|
104
|
+
}
|
|
105
|
+
asHours() {
|
|
106
|
+
return this.inner.asHours();
|
|
107
|
+
}
|
|
108
|
+
asDays() {
|
|
109
|
+
return this.inner.asDays();
|
|
110
|
+
}
|
|
111
|
+
as(unit) {
|
|
112
|
+
return this.inner.as(unit);
|
|
113
|
+
}
|
|
114
|
+
toISOString() {
|
|
115
|
+
return this.inner.toISOString();
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Escape hatch for the underlying dayjs duration.
|
|
119
|
+
*/
|
|
120
|
+
toDayjs() {
|
|
121
|
+
return this.inner;
|
|
122
|
+
}
|
|
123
|
+
};
|
|
12
124
|
const isDateTime = (value) => {
|
|
13
|
-
return
|
|
125
|
+
return value instanceof DateTime;
|
|
126
|
+
};
|
|
127
|
+
const toDayjs = (value) => {
|
|
128
|
+
if (value instanceof DateTime) return value.toDayjs();
|
|
129
|
+
return DayjsApi(value);
|
|
14
130
|
};
|
|
15
131
|
var DateTimeProvider = class DateTimeProvider {
|
|
16
132
|
static PLUGINS = [
|
|
@@ -25,7 +141,7 @@ var DateTimeProvider = class DateTimeProvider {
|
|
|
25
141
|
timeouts = [];
|
|
26
142
|
intervals = [];
|
|
27
143
|
constructor() {
|
|
28
|
-
for (const plugin of DateTimeProvider.PLUGINS)
|
|
144
|
+
for (const plugin of DateTimeProvider.PLUGINS) DayjsApi.extend(plugin);
|
|
29
145
|
}
|
|
30
146
|
onStart = $hook({
|
|
31
147
|
on: "start",
|
|
@@ -49,22 +165,23 @@ var DateTimeProvider = class DateTimeProvider {
|
|
|
49
165
|
}
|
|
50
166
|
});
|
|
51
167
|
setLocale(locale) {
|
|
52
|
-
|
|
168
|
+
DayjsApi.locale(locale);
|
|
53
169
|
}
|
|
54
170
|
isDateTime(value) {
|
|
55
|
-
return
|
|
171
|
+
return value instanceof DateTime;
|
|
56
172
|
}
|
|
57
173
|
/**
|
|
58
174
|
* Create a new UTC DateTime instance.
|
|
59
175
|
*/
|
|
60
176
|
utc(date) {
|
|
61
|
-
return
|
|
177
|
+
return new DateTime(DayjsApi.utc(unwrap(date)));
|
|
62
178
|
}
|
|
63
179
|
/**
|
|
64
180
|
* Create a new DateTime instance.
|
|
65
181
|
*/
|
|
66
182
|
of(date) {
|
|
67
|
-
|
|
183
|
+
if (date instanceof DateTime) return date;
|
|
184
|
+
return new DateTime(DayjsApi(date));
|
|
68
185
|
}
|
|
69
186
|
/**
|
|
70
187
|
* Get the current date as a string.
|
|
@@ -103,19 +220,20 @@ var DateTimeProvider = class DateTimeProvider {
|
|
|
103
220
|
*/
|
|
104
221
|
getCurrentDate() {
|
|
105
222
|
if (this.ref) return this.ref;
|
|
106
|
-
return
|
|
223
|
+
return new DateTime(DayjsApi());
|
|
107
224
|
}
|
|
108
225
|
/**
|
|
109
226
|
* Create a new Duration instance.
|
|
110
227
|
*/
|
|
111
228
|
duration = (duration, unit) => {
|
|
112
|
-
if (
|
|
113
|
-
if (
|
|
229
|
+
if (duration instanceof Duration) return duration;
|
|
230
|
+
if (Array.isArray(duration)) return new Duration(DayjsApi.duration(duration[0], duration[1]));
|
|
231
|
+
if (typeof duration === "number") return new Duration(DayjsApi.duration(duration, unit || "milliseconds"));
|
|
114
232
|
return duration;
|
|
115
233
|
};
|
|
116
234
|
isDurationLike(value) {
|
|
117
235
|
try {
|
|
118
|
-
return
|
|
236
|
+
return DayjsApi.isDuration(this.duration(value).toDayjs());
|
|
119
237
|
} catch {
|
|
120
238
|
return false;
|
|
121
239
|
}
|
|
@@ -165,7 +283,7 @@ var DateTimeProvider = class DateTimeProvider {
|
|
|
165
283
|
*/
|
|
166
284
|
createTimeout(callback, duration, now) {
|
|
167
285
|
if (this.ref && now) {
|
|
168
|
-
if (this.of(now).add(this.duration(duration)) < this.now()) callback();
|
|
286
|
+
if (this.of(now).add(this.duration(duration)).valueOf() < this.now().valueOf()) callback();
|
|
169
287
|
return {
|
|
170
288
|
now,
|
|
171
289
|
duration: 0,
|
|
@@ -258,6 +376,10 @@ var DateTimeProvider = class DateTimeProvider {
|
|
|
258
376
|
this.ref = null;
|
|
259
377
|
}
|
|
260
378
|
};
|
|
379
|
+
const unwrap = (value) => {
|
|
380
|
+
if (value instanceof DateTime) return value.toDayjs();
|
|
381
|
+
return value;
|
|
382
|
+
};
|
|
261
383
|
//#endregion
|
|
262
384
|
//#region ../../src/datetime/primitives/$interval.ts
|
|
263
385
|
/**
|
|
@@ -440,6 +562,6 @@ const AlephaDateTime = $module({
|
|
|
440
562
|
services: [DateTimeProvider]
|
|
441
563
|
});
|
|
442
564
|
//#endregion
|
|
443
|
-
export { $debounce, $interval, $throttle, $timeout, AlephaDateTime, DateTimeProvider,
|
|
565
|
+
export { $debounce, $interval, $throttle, $timeout, AlephaDateTime, DateTime, DateTimeProvider, Duration, IntervalPrimitive, isDateTime };
|
|
444
566
|
|
|
445
567
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":[],"sources":["../../src/datetime/providers/DateTimeProvider.ts","../../src/datetime/primitives/$interval.ts","../../src/datetime/primitives/$debounce.ts","../../src/datetime/primitives/$throttle.ts","../../src/datetime/primitives/$timeout.ts","../../src/datetime/index.ts"],"sourcesContent":["import \"dayjs/plugin/relativeTime.js\";\nimport \"dayjs/plugin/duration.js\";\nimport \"dayjs/plugin/utc.js\";\nimport \"dayjs/plugin/timezone.js\";\nimport \"dayjs/plugin/localizedFormat.js\";\nimport \"dayjs/locale/ar.js\";\nimport \"dayjs/locale/fr.js\";\nimport { $hook, $inject, Alepha } from \"alepha\";\nimport DayjsApi, {\n type Dayjs,\n type ManipulateType,\n type PluginFunc,\n} from \"dayjs\";\nimport dayjsDuration from \"dayjs/plugin/duration.js\";\nimport dayjsLocalizedFormat from \"dayjs/plugin/localizedFormat.js\";\nimport dayjsRelativeTime from \"dayjs/plugin/relativeTime.js\";\nimport dayjsTimezone from \"dayjs/plugin/timezone.js\";\nimport dayjsUtc from \"dayjs/plugin/utc.js\";\n\nexport type DateTime = DayjsApi.Dayjs;\nexport type Duration = dayjsDuration.Duration;\nexport type DurationLike =\n | number\n | dayjsDuration.Duration\n | [number, ManipulateType];\n\nexport const dayjs = DayjsApi;\nexport const isDateTime = (value: unknown): value is DateTime => {\n return dayjs.isDayjs(value);\n};\n\nexport class DateTimeProvider {\n public static PLUGINS: Array<PluginFunc<any>> = [\n dayjsDuration,\n dayjsRelativeTime,\n dayjsUtc,\n dayjsTimezone,\n dayjsLocalizedFormat,\n ];\n\n protected alepha = $inject(Alepha);\n protected ref: DateTime | null = null;\n protected readonly timeouts: Timeout[] = [];\n protected readonly intervals: Interval[] = [];\n\n constructor() {\n for (const plugin of DateTimeProvider.PLUGINS) {\n dayjs.extend(plugin);\n }\n }\n\n protected readonly onStart = $hook({\n on: \"start\",\n handler: async () => {\n // we start intervals now but first tick will be rejected as App is not ready yet\n await Promise.all(\n this.intervals.map(async (interval) => {\n if (interval.timer != null) {\n return;\n }\n await interval.run();\n interval.timer = setInterval(interval.run, interval.duration);\n }),\n );\n },\n });\n\n protected readonly onStop = $hook({\n on: \"stop\",\n handler: () => {\n for (const timeout of [...this.timeouts]) {\n this.clearTimeout(timeout);\n }\n\n for (const interval of this.intervals) {\n clearInterval(interval.timer);\n interval.duration = 0;\n interval.timer = null;\n }\n },\n });\n\n public setLocale(locale: string): void {\n dayjs.locale(locale);\n }\n\n public isDateTime(value: unknown): value is DateTime {\n return dayjs.isDayjs(value);\n }\n\n /**\n * Create a new UTC DateTime instance.\n */\n public utc(\n date: string | number | Date | Dayjs | null | undefined,\n ): DateTime {\n return dayjs.utc(date);\n }\n\n /**\n * Create a new DateTime instance.\n */\n public of(date: string | number | Date | Dayjs | null | undefined): DateTime {\n return dayjs(date);\n }\n\n /**\n * Get the current date as a string.\n */\n public toISOString(date: Date | string | DateTime = this.now()): string {\n return this.of(date).toISOString();\n }\n\n /**\n * Get the current date.\n */\n public now(): DateTime {\n return this.getCurrentDate();\n }\n\n /**\n * Get the current date as a string.\n *\n * This is much faster than `DateTimeProvider.now().toISOString()` as it avoids creating a DateTime instance.\n */\n public nowISOString(): string {\n if (this.ref) {\n return this.ref.toISOString();\n }\n return new Date().toISOString();\n }\n\n /**\n * Get the current date as milliseconds since epoch.\n *\n * This is much faster than `DateTimeProvider.now().valueOf()` as it avoids creating a DateTime instance.\n */\n public nowMillis(): number {\n if (this.ref) {\n return this.ref.valueOf();\n }\n return Date.now();\n }\n\n /**\n * Get the current date as a string.\n *\n * @protected\n */\n protected getCurrentDate(): DateTime {\n if (this.ref) {\n return this.ref;\n }\n\n return dayjs();\n }\n\n /**\n * Create a new Duration instance.\n */\n public duration = (\n duration: DurationLike,\n unit?: ManipulateType,\n ): Duration => {\n if (Array.isArray(duration)) {\n return dayjs.duration(duration[0], duration[1]);\n }\n\n if (typeof duration === \"number\") {\n return dayjs.duration(duration, unit || \"milliseconds\");\n }\n\n return duration;\n };\n\n public isDurationLike(value: unknown): value is DurationLike {\n try {\n return dayjs.isDuration(this.duration(value as DurationLike));\n } catch {\n return false;\n }\n }\n\n // -------------------------------------------------------------------------------------------------------------------\n\n // Timer Management\n\n /**\n * Return a promise that resolves after the next tick.\n * It uses `setTimeout` with 0 ms delay.\n */\n public async tick(): Promise<void> {\n await new Promise((resolve) => setTimeout(resolve, 0));\n }\n\n /**\n * Wait for a certain duration.\n *\n * You can clear the timeout by using the `AbortSignal` API.\n * Aborted signal will resolve the promise immediately, it does not reject it.\n */\n public wait(\n duration: DurationLike,\n options: {\n signal?: AbortSignal;\n now?: number;\n } = {},\n ): Promise<void> {\n return new Promise((resolve) => {\n let clearTimeout: any;\n let callback: any;\n\n const timeout = this.createTimeout(\n () => {\n if (options.signal && clearTimeout) {\n options.signal.removeEventListener(\"abort\", callback);\n }\n resolve();\n },\n duration,\n options.now,\n );\n\n if (options.signal) {\n clearTimeout = () => this.clearTimeout(timeout);\n callback = () => {\n clearTimeout();\n resolve();\n };\n options.signal.addEventListener(\"abort\", callback);\n }\n });\n }\n\n public createInterval(\n run: () => unknown,\n duration: DurationLike,\n start = false,\n ): Interval {\n const interval: Interval = {\n run,\n duration: this.duration(duration).asMilliseconds(),\n };\n\n this.intervals.push(interval);\n\n if (start) {\n interval.timer = setInterval(interval.run, interval.duration);\n }\n\n return interval;\n }\n\n /**\n * Run a callback after a certain duration.\n */\n public createTimeout(\n callback: () => void,\n duration: DurationLike,\n now?: number,\n ): Timeout {\n if (this.ref && now) {\n const next = this.of(now).add(this.duration(duration));\n if (next < this.now()) {\n callback();\n }\n return {\n now,\n duration: 0,\n callback: () => {},\n clear: () => {},\n };\n }\n\n const timeout: Timeout = {\n now: now ?? this.now().valueOf(),\n duration: this.duration(duration).asMilliseconds(),\n callback,\n clear: () => this.clearTimeout(timeout),\n };\n\n timeout.timer = setTimeout(() => {\n const index = this.timeouts.indexOf(timeout);\n if (index !== -1) {\n this.timeouts.splice(index, 1);\n }\n timeout.callback();\n }, timeout.duration);\n\n this.timeouts.push(timeout);\n\n return timeout;\n }\n\n public clearTimeout(timeout: Timeout): void {\n clearTimeout(timeout.timer);\n timeout.duration = 0;\n timeout.timer = null;\n const index = this.timeouts.indexOf(timeout);\n if (index !== -1) {\n this.timeouts.splice(index, 1);\n }\n }\n\n public clearInterval(interval: Interval): void {\n clearInterval(interval.timer);\n interval.duration = 0;\n interval.timer = null;\n }\n\n /**\n * Run a function with a deadline.\n */\n public async deadline<T>(\n fn: (signal: AbortSignal) => Promise<T>,\n duration: DurationLike,\n ): Promise<T> {\n const abort = new AbortController();\n const timeout = this.createTimeout(() => abort.abort(), duration);\n try {\n return await fn(abort.signal);\n } finally {\n this.clearTimeout(timeout);\n }\n }\n\n // -------------------------------------------------------------------------------------------------------------------\n\n // Testing\n\n /**\n * Add time to the current date.\n */\n public async travel(\n duration: DurationLike,\n unit?: ManipulateType,\n ): Promise<void> {\n this.ref = this.ref || this.now();\n const ms = this.duration(duration, unit).asMilliseconds();\n const now = this.nowMillis();\n this.ref = this.ref.add(this.duration(duration, unit));\n\n for (const timeout of [...this.timeouts]) {\n if (!timeout.timer) {\n continue;\n }\n\n clearTimeout(timeout.timer);\n timeout.timer = null;\n\n const spent = now - timeout.now;\n timeout.duration = timeout.duration - spent - ms;\n\n if (timeout.duration <= 0) {\n const index = this.timeouts.indexOf(timeout);\n if (index !== -1) {\n this.timeouts.splice(index, 1);\n }\n timeout.callback();\n } else {\n timeout.timer = setTimeout(() => {\n const index = this.timeouts.indexOf(timeout);\n if (index !== -1) {\n this.timeouts.splice(index, 1);\n }\n timeout.callback();\n }, timeout.duration);\n }\n }\n\n for (const interval of this.intervals) {\n if (!interval.timer) {\n continue;\n }\n\n clearInterval(interval.timer);\n\n const repeat = Math.floor(ms / interval.duration);\n for (let i = 0; i < repeat; i++) {\n await interval.run();\n }\n\n // Keep intervals suspended — they only fire during travel() calls\n interval.timer = null;\n }\n\n await this.tick();\n }\n\n /**\n * Stop the time.\n */\n public pause(): DateTime {\n this.ref = this.ref || this.now();\n return this.ref;\n }\n\n /**\n * Reset the reference date.\n */\n public reset(): void {\n this.ref = null;\n }\n}\n\nexport interface Interval {\n timer?: any;\n duration: number;\n run: () => unknown;\n}\n\nexport interface Timeout {\n now: number;\n timer?: any;\n duration: number;\n callback: () => void;\n clear: () => void;\n}\n","import { $inject, createPrimitive, KIND, Primitive } from \"alepha\";\nimport {\n DateTimeProvider,\n type DurationLike,\n} from \"../providers/DateTimeProvider.ts\";\n\n/**\n * Run a function periodically.\n * It uses the `setInterval` internally.\n * It starts by default when the context starts and stops when the context stops.\n */\nexport const $interval = (options: IntervalPrimitiveOptions) =>\n createPrimitive(IntervalPrimitive, options);\n\n// ---------------------------------------------------------------------------------------------------------------------\n\nexport interface IntervalPrimitiveOptions {\n /**\n * The interval handler.\n */\n handler: () => unknown;\n\n /**\n * The interval duration.\n */\n duration: DurationLike;\n}\n\n// ---------------------------------------------------------------------------------------------------------------------\n\nexport class IntervalPrimitive extends Primitive<IntervalPrimitiveOptions> {\n protected readonly dateTimeProvider = $inject(DateTimeProvider);\n\n public called = 0;\n\n protected onInit() {\n this.dateTimeProvider.createInterval(async () => {\n await this.options.handler();\n this.called += 1;\n }, this.options.duration);\n }\n}\n\n$interval[KIND] = IntervalPrimitive;\n","import { createMiddleware, type Middleware } from \"alepha\";\nimport {\n DateTimeProvider,\n type DurationLike,\n} from \"../providers/DateTimeProvider.ts\";\n\nexport interface DebounceOptions {\n /**\n * Coalescing window. Concurrent calls within this window share one execution.\n */\n delay: DurationLike;\n\n /**\n * Key function to group calls. Calls with the same key are coalesced.\n * Defaults to `JSON.stringify(args)`.\n */\n key?: (...args: any[]) => string;\n}\n\n/**\n * Middleware that coalesces concurrent calls with the same key into a single handler execution.\n *\n * All callers within the delay window receive the same result. No storage —\n * once the handler finishes, the next call starts fresh. Process-local.\n *\n * **Use case**: thundering herd protection — cache expires, 100 requests\n * hit the same endpoint, debounce ensures one rebuild.\n *\n * ```typescript\n * class SearchController {\n * search = $action({\n * use: [$debounce({ delay: [200, \"ms\"], key: (req) => req.query.q })],\n * handler: async ({ query }) => this.searchService.search(query.q),\n * });\n * }\n * ```\n */\nexport const $debounce = (options: DebounceOptions): Middleware => {\n return createMiddleware({\n name: \"$debounce\",\n options: options as unknown as Record<string, unknown>,\n handler: ({ alepha, next }) => {\n const dateTimeProvider = alepha.inject(DateTimeProvider);\n const pending = new Map<string, Promise<any>>();\n\n return async (...args) => {\n const key = options.key?.(...args) ?? JSON.stringify(args);\n\n const existing = pending.get(key);\n if (existing) {\n return existing;\n }\n\n let resolve: (value: any) => void;\n let reject: (error: any) => void;\n const promise = new Promise<any>((res, rej) => {\n resolve = res;\n reject = rej;\n });\n\n dateTimeProvider.createTimeout(async () => {\n try {\n const result = await next(...args);\n resolve!(result);\n } catch (error) {\n reject!(error);\n } finally {\n pending.delete(key);\n }\n }, options.delay);\n\n pending.set(key, promise);\n return promise;\n };\n },\n });\n};\n","import { createMiddleware, type Middleware } from \"alepha\";\nimport {\n DateTimeProvider,\n type DurationLike,\n} from \"../providers/DateTimeProvider.ts\";\n\nexport interface ThrottleOptions {\n /**\n * Max calls per window.\n */\n rate: number;\n\n /**\n * Window duration.\n */\n per: DurationLike;\n}\n\n/**\n * Middleware that rate-controls handler execution using a token bucket.\n *\n * Excess calls are **delayed** until capacity is available — never rejected.\n * Process-local (not distributed). Use `$rateLimit` for distributed rate limiting.\n *\n * **Use case**: protect an external API from your own traffic.\n *\n * ```typescript\n * class PaymentController {\n * charge = $action({\n * use: [$throttle({ rate: 80, per: [1, \"second\"] })],\n * handler: async ({ body }) => this.stripe.charges.create(body),\n * });\n * }\n * ```\n */\nexport const $throttle = (options: ThrottleOptions): Middleware => {\n return createMiddleware({\n name: \"$throttle\",\n options: options as unknown as Record<string, unknown>,\n handler: ({ alepha, next }) => {\n const dateTimeProvider = alepha.inject(DateTimeProvider);\n const intervalMs = dateTimeProvider\n .duration(options.per)\n .asMilliseconds();\n\n let tokens = options.rate;\n let lastRefill = dateTimeProvider.nowMillis();\n\n return async (...args) => {\n const now = dateTimeProvider.nowMillis();\n const elapsed = now - lastRefill;\n const refill = Math.floor(elapsed / intervalMs) * options.rate;\n\n if (refill > 0) {\n tokens = Math.min(options.rate, tokens + refill);\n lastRefill += Math.floor(elapsed / intervalMs) * intervalMs;\n }\n\n if (tokens <= 0) {\n const waitMs = intervalMs - (now - lastRefill);\n await dateTimeProvider.wait(waitMs);\n tokens = options.rate;\n lastRefill = dateTimeProvider.nowMillis();\n }\n\n tokens--;\n return next(...args);\n };\n },\n });\n};\n","import { AlephaError, createMiddleware, type Middleware } from \"alepha\";\nimport {\n DateTimeProvider,\n type DurationLike,\n} from \"../providers/DateTimeProvider.ts\";\n\n/**\n * Middleware that aborts handler execution if it exceeds a duration limit.\n *\n * Uses `Promise.race` with a managed timeout from `DateTimeProvider` —\n * if the handler doesn't resolve before the deadline, the promise rejects.\n * Uses managed timeouts so it works with `DateTimeProvider.travel()` in tests.\n *\n * ```typescript\n * class OrderService {\n * processOrder = $pipeline({\n * use: [$timeout([30, \"seconds\"])],\n * handler: async (orderId: string) => {\n * return await this.orders.updateById(orderId, { status: \"paid\" });\n * },\n * });\n * }\n * ```\n */\nexport const $timeout = (duration: DurationLike): Middleware => {\n return createMiddleware({\n name: \"$timeout\",\n options: { duration },\n handler: ({ alepha, next }) => {\n const dateTimeProvider = alepha.inject(DateTimeProvider);\n\n return async (...args) => {\n let rejectTimeout: (reason: Error) => void;\n const timeoutPromise = new Promise<never>((_, reject) => {\n rejectTimeout = reject;\n });\n\n const timer = dateTimeProvider.createTimeout(() => {\n rejectTimeout(new AlephaError(\"$timeout: handler exceeded deadline\"));\n }, duration);\n\n try {\n return await Promise.race([next(...args), timeoutPromise]);\n } finally {\n dateTimeProvider.clearTimeout(timer);\n }\n };\n },\n });\n};\n","import { $module } from \"alepha\";\nimport { $interval } from \"./primitives/$interval.ts\";\nimport { DateTimeProvider } from \"./providers/DateTimeProvider.ts\";\n\nexport * from \"./primitives/$debounce.ts\";\nexport * from \"./primitives/$interval.ts\";\nexport * from \"./primitives/$throttle.ts\";\nexport * from \"./primitives/$timeout.ts\";\nexport * from \"./providers/DateTimeProvider.ts\";\n\n// ---------------------------------------------------------------------------------------------------------------------\n\n/**\n * Date and time operations.\n *\n * **Features:**\n * - Recurring interval definitions\n * - Duration parsing (ISO 8601, human-readable)\n * - Timezone support\n * - Dayjs integration\n *\n * @module alepha.datetime\n */\nexport const AlephaDateTime = $module({\n name: \"alepha.datetime\",\n primitives: [$interval],\n services: [DateTimeProvider],\n});\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../../src/datetime/providers/DateTimeProvider.ts","../../src/datetime/primitives/$interval.ts","../../src/datetime/primitives/$debounce.ts","../../src/datetime/primitives/$throttle.ts","../../src/datetime/primitives/$timeout.ts","../../src/datetime/index.ts"],"sourcesContent":["import \"dayjs/plugin/relativeTime.js\";\nimport \"dayjs/plugin/duration.js\";\nimport \"dayjs/plugin/utc.js\";\nimport \"dayjs/plugin/timezone.js\";\nimport \"dayjs/plugin/localizedFormat.js\";\nimport \"dayjs/locale/ar.js\";\nimport \"dayjs/locale/fr.js\";\nimport { $hook, $inject, Alepha } from \"alepha\";\nimport DayjsApi, {\n type Dayjs,\n type ManipulateType,\n type OpUnitType,\n type PluginFunc,\n type QUnitType,\n} from \"dayjs\";\nimport dayjsDuration, { type DurationUnitType } from \"dayjs/plugin/duration.js\";\nimport dayjsLocalizedFormat from \"dayjs/plugin/localizedFormat.js\";\nimport dayjsRelativeTime from \"dayjs/plugin/relativeTime.js\";\nimport dayjsTimezone from \"dayjs/plugin/timezone.js\";\nimport dayjsUtc from \"dayjs/plugin/utc.js\";\n\nexport type { DurationUnitType, ManipulateType, OpUnitType, QUnitType };\n\nexport type DateTimeInput = string | number | Date | DateTime | Dayjs;\n\nexport type DurationLike = number | Duration | [number, ManipulateType];\n\n/**\n * Immutable wrapper around the underlying date-time engine.\n *\n * Designed to isolate consumers from the engine in use (currently dayjs).\n * Methods that produce a new value return a new `DateTime` instance.\n */\nexport class DateTime {\n protected readonly inner: Dayjs;\n\n constructor(inner: Dayjs) {\n this.inner = inner;\n }\n\n /**\n * Add a duration to this date-time.\n */\n add(amount: number, unit?: ManipulateType): DateTime;\n add(duration: Duration): DateTime;\n add(amount: number | Duration, unit?: ManipulateType): DateTime {\n if (amount instanceof Duration) {\n return new DateTime(this.inner.add(amount.toDayjs()));\n }\n return new DateTime(this.inner.add(amount, unit));\n }\n\n /**\n * Subtract a duration from this date-time.\n */\n subtract(amount: number, unit?: ManipulateType): DateTime;\n subtract(duration: Duration): DateTime;\n subtract(amount: number | Duration, unit?: ManipulateType): DateTime {\n if (amount instanceof Duration) {\n return new DateTime(this.inner.subtract(amount.toDayjs()));\n }\n return new DateTime(this.inner.subtract(amount, unit));\n }\n\n startOf(unit: OpUnitType): DateTime {\n return new DateTime(this.inner.startOf(unit));\n }\n\n endOf(unit: OpUnitType): DateTime {\n return new DateTime(this.inner.endOf(unit));\n }\n\n isAfter(other: DateTimeInput): boolean {\n return this.inner.isAfter(toDayjs(other));\n }\n\n isBefore(other: DateTimeInput): boolean {\n return this.inner.isBefore(toDayjs(other));\n }\n\n isSame(other: DateTimeInput, unit?: OpUnitType): boolean {\n return this.inner.isSame(toDayjs(other), unit);\n }\n\n diff(other: DateTimeInput, unit?: QUnitType | OpUnitType): number {\n return this.inner.diff(toDayjs(other), unit);\n }\n\n tz(timezone: string): DateTime {\n return new DateTime(this.inner.tz(timezone));\n }\n\n locale(lang: string): DateTime {\n return new DateTime(this.inner.locale(lang));\n }\n\n format(template?: string): string {\n return this.inner.format(template);\n }\n\n fromNow(withoutSuffix?: boolean): string {\n return this.inner.fromNow(withoutSuffix);\n }\n\n toISOString(): string {\n return this.inner.toISOString();\n }\n\n toDate(): Date {\n return this.inner.toDate();\n }\n\n valueOf(): number {\n return this.inner.valueOf();\n }\n\n unix(): number {\n return this.inner.unix();\n }\n\n toJSON(): string {\n return this.inner.toISOString();\n }\n\n toString(): string {\n return this.inner.toISOString();\n }\n\n /**\n * Escape hatch for the underlying dayjs instance.\n *\n * Use sparingly — anything calling this becomes coupled to dayjs and\n * will need to migrate when the engine is replaced.\n */\n toDayjs(): Dayjs {\n return this.inner;\n }\n}\n\n/**\n * Immutable wrapper around the underlying duration engine.\n */\nexport class Duration {\n protected readonly inner: dayjsDuration.Duration;\n\n constructor(inner: dayjsDuration.Duration) {\n this.inner = inner;\n }\n\n asMilliseconds(): number {\n return this.inner.asMilliseconds();\n }\n\n asSeconds(): number {\n return this.inner.asSeconds();\n }\n\n asMinutes(): number {\n return this.inner.asMinutes();\n }\n\n asHours(): number {\n return this.inner.asHours();\n }\n\n asDays(): number {\n return this.inner.asDays();\n }\n\n as(unit: DurationUnitType): number {\n return this.inner.as(unit);\n }\n\n toISOString(): string {\n return this.inner.toISOString();\n }\n\n /**\n * Escape hatch for the underlying dayjs duration.\n */\n toDayjs(): dayjsDuration.Duration {\n return this.inner;\n }\n}\n\nexport const isDateTime = (value: unknown): value is DateTime => {\n return value instanceof DateTime;\n};\n\nconst toDayjs = (value: DateTimeInput): Dayjs => {\n if (value instanceof DateTime) {\n return value.toDayjs();\n }\n return DayjsApi(value as any);\n};\n\nexport class DateTimeProvider {\n public static PLUGINS: Array<PluginFunc<any>> = [\n dayjsDuration,\n dayjsRelativeTime,\n dayjsUtc,\n dayjsTimezone,\n dayjsLocalizedFormat,\n ];\n\n protected alepha = $inject(Alepha);\n protected ref: DateTime | null = null;\n protected readonly timeouts: Timeout[] = [];\n protected readonly intervals: Interval[] = [];\n\n constructor() {\n for (const plugin of DateTimeProvider.PLUGINS) {\n DayjsApi.extend(plugin);\n }\n }\n\n protected readonly onStart = $hook({\n on: \"start\",\n handler: async () => {\n // we start intervals now but first tick will be rejected as App is not ready yet\n await Promise.all(\n this.intervals.map(async (interval) => {\n if (interval.timer != null) {\n return;\n }\n await interval.run();\n interval.timer = setInterval(interval.run, interval.duration);\n }),\n );\n },\n });\n\n protected readonly onStop = $hook({\n on: \"stop\",\n handler: () => {\n for (const timeout of [...this.timeouts]) {\n this.clearTimeout(timeout);\n }\n\n for (const interval of this.intervals) {\n clearInterval(interval.timer);\n interval.duration = 0;\n interval.timer = null;\n }\n },\n });\n\n public setLocale(locale: string): void {\n DayjsApi.locale(locale);\n }\n\n public isDateTime(value: unknown): value is DateTime {\n return value instanceof DateTime;\n }\n\n /**\n * Create a new UTC DateTime instance.\n */\n public utc(date: DateTimeInput | null | undefined): DateTime {\n return new DateTime(DayjsApi.utc(unwrap(date)));\n }\n\n /**\n * Create a new DateTime instance.\n */\n public of(date: DateTimeInput | null | undefined): DateTime {\n if (date instanceof DateTime) {\n return date;\n }\n return new DateTime(DayjsApi(date as any));\n }\n\n /**\n * Get the current date as a string.\n */\n public toISOString(date: DateTimeInput = this.now()): string {\n return this.of(date).toISOString();\n }\n\n /**\n * Get the current date.\n */\n public now(): DateTime {\n return this.getCurrentDate();\n }\n\n /**\n * Get the current date as a string.\n *\n * This is much faster than `DateTimeProvider.now().toISOString()` as it avoids creating a DateTime instance.\n */\n public nowISOString(): string {\n if (this.ref) {\n return this.ref.toISOString();\n }\n return new Date().toISOString();\n }\n\n /**\n * Get the current date as milliseconds since epoch.\n *\n * This is much faster than `DateTimeProvider.now().valueOf()` as it avoids creating a DateTime instance.\n */\n public nowMillis(): number {\n if (this.ref) {\n return this.ref.valueOf();\n }\n return Date.now();\n }\n\n /**\n * Get the current date as a string.\n *\n * @protected\n */\n protected getCurrentDate(): DateTime {\n if (this.ref) {\n return this.ref;\n }\n\n return new DateTime(DayjsApi());\n }\n\n /**\n * Create a new Duration instance.\n */\n public duration = (\n duration: DurationLike,\n unit?: ManipulateType,\n ): Duration => {\n if (duration instanceof Duration) {\n return duration;\n }\n\n if (Array.isArray(duration)) {\n return new Duration(DayjsApi.duration(duration[0], duration[1]));\n }\n\n if (typeof duration === \"number\") {\n return new Duration(DayjsApi.duration(duration, unit || \"milliseconds\"));\n }\n\n return duration;\n };\n\n public isDurationLike(value: unknown): value is DurationLike {\n try {\n return DayjsApi.isDuration(\n this.duration(value as DurationLike).toDayjs(),\n );\n } catch {\n return false;\n }\n }\n\n // -------------------------------------------------------------------------------------------------------------------\n\n // Timer Management\n\n /**\n * Return a promise that resolves after the next tick.\n * It uses `setTimeout` with 0 ms delay.\n */\n public async tick(): Promise<void> {\n await new Promise((resolve) => setTimeout(resolve, 0));\n }\n\n /**\n * Wait for a certain duration.\n *\n * You can clear the timeout by using the `AbortSignal` API.\n * Aborted signal will resolve the promise immediately, it does not reject it.\n */\n public wait(\n duration: DurationLike,\n options: {\n signal?: AbortSignal;\n now?: number;\n } = {},\n ): Promise<void> {\n return new Promise((resolve) => {\n let clearTimeout: any;\n let callback: any;\n\n const timeout = this.createTimeout(\n () => {\n if (options.signal && clearTimeout) {\n options.signal.removeEventListener(\"abort\", callback);\n }\n resolve();\n },\n duration,\n options.now,\n );\n\n if (options.signal) {\n clearTimeout = () => this.clearTimeout(timeout);\n callback = () => {\n clearTimeout();\n resolve();\n };\n options.signal.addEventListener(\"abort\", callback);\n }\n });\n }\n\n public createInterval(\n run: () => unknown,\n duration: DurationLike,\n start = false,\n ): Interval {\n const interval: Interval = {\n run,\n duration: this.duration(duration).asMilliseconds(),\n };\n\n this.intervals.push(interval);\n\n if (start) {\n interval.timer = setInterval(interval.run, interval.duration);\n }\n\n return interval;\n }\n\n /**\n * Run a callback after a certain duration.\n */\n public createTimeout(\n callback: () => void,\n duration: DurationLike,\n now?: number,\n ): Timeout {\n if (this.ref && now) {\n const next = this.of(now).add(this.duration(duration));\n if (next.valueOf() < this.now().valueOf()) {\n callback();\n }\n return {\n now,\n duration: 0,\n callback: () => {},\n clear: () => {},\n };\n }\n\n const timeout: Timeout = {\n now: now ?? this.now().valueOf(),\n duration: this.duration(duration).asMilliseconds(),\n callback,\n clear: () => this.clearTimeout(timeout),\n };\n\n timeout.timer = setTimeout(() => {\n const index = this.timeouts.indexOf(timeout);\n if (index !== -1) {\n this.timeouts.splice(index, 1);\n }\n timeout.callback();\n }, timeout.duration);\n\n this.timeouts.push(timeout);\n\n return timeout;\n }\n\n public clearTimeout(timeout: Timeout): void {\n clearTimeout(timeout.timer);\n timeout.duration = 0;\n timeout.timer = null;\n const index = this.timeouts.indexOf(timeout);\n if (index !== -1) {\n this.timeouts.splice(index, 1);\n }\n }\n\n public clearInterval(interval: Interval): void {\n clearInterval(interval.timer);\n interval.duration = 0;\n interval.timer = null;\n }\n\n /**\n * Run a function with a deadline.\n */\n public async deadline<T>(\n fn: (signal: AbortSignal) => Promise<T>,\n duration: DurationLike,\n ): Promise<T> {\n const abort = new AbortController();\n const timeout = this.createTimeout(() => abort.abort(), duration);\n try {\n return await fn(abort.signal);\n } finally {\n this.clearTimeout(timeout);\n }\n }\n\n // -------------------------------------------------------------------------------------------------------------------\n\n // Testing\n\n /**\n * Add time to the current date.\n */\n public async travel(\n duration: DurationLike,\n unit?: ManipulateType,\n ): Promise<void> {\n this.ref = this.ref || this.now();\n const ms = this.duration(duration, unit).asMilliseconds();\n const now = this.nowMillis();\n this.ref = this.ref.add(this.duration(duration, unit));\n\n for (const timeout of [...this.timeouts]) {\n if (!timeout.timer) {\n continue;\n }\n\n clearTimeout(timeout.timer);\n timeout.timer = null;\n\n const spent = now - timeout.now;\n timeout.duration = timeout.duration - spent - ms;\n\n if (timeout.duration <= 0) {\n const index = this.timeouts.indexOf(timeout);\n if (index !== -1) {\n this.timeouts.splice(index, 1);\n }\n timeout.callback();\n } else {\n timeout.timer = setTimeout(() => {\n const index = this.timeouts.indexOf(timeout);\n if (index !== -1) {\n this.timeouts.splice(index, 1);\n }\n timeout.callback();\n }, timeout.duration);\n }\n }\n\n for (const interval of this.intervals) {\n if (!interval.timer) {\n continue;\n }\n\n clearInterval(interval.timer);\n\n const repeat = Math.floor(ms / interval.duration);\n for (let i = 0; i < repeat; i++) {\n await interval.run();\n }\n\n // Keep intervals suspended — they only fire during travel() calls\n interval.timer = null;\n }\n\n await this.tick();\n }\n\n /**\n * Stop the time.\n */\n public pause(): DateTime {\n this.ref = this.ref || this.now();\n return this.ref;\n }\n\n /**\n * Reset the reference date.\n */\n public reset(): void {\n this.ref = null;\n }\n}\n\nconst unwrap = (value: DateTimeInput | null | undefined): any => {\n if (value instanceof DateTime) {\n return value.toDayjs();\n }\n return value;\n};\n\nexport interface Interval {\n timer?: any;\n duration: number;\n run: () => unknown;\n}\n\nexport interface Timeout {\n now: number;\n timer?: any;\n duration: number;\n callback: () => void;\n clear: () => void;\n}\n","import { $inject, createPrimitive, KIND, Primitive } from \"alepha\";\nimport {\n DateTimeProvider,\n type DurationLike,\n} from \"../providers/DateTimeProvider.ts\";\n\n/**\n * Run a function periodically.\n * It uses the `setInterval` internally.\n * It starts by default when the context starts and stops when the context stops.\n */\nexport const $interval = (options: IntervalPrimitiveOptions) =>\n createPrimitive(IntervalPrimitive, options);\n\n// ---------------------------------------------------------------------------------------------------------------------\n\nexport interface IntervalPrimitiveOptions {\n /**\n * The interval handler.\n */\n handler: () => unknown;\n\n /**\n * The interval duration.\n */\n duration: DurationLike;\n}\n\n// ---------------------------------------------------------------------------------------------------------------------\n\nexport class IntervalPrimitive extends Primitive<IntervalPrimitiveOptions> {\n protected readonly dateTimeProvider = $inject(DateTimeProvider);\n\n public called = 0;\n\n protected onInit() {\n this.dateTimeProvider.createInterval(async () => {\n await this.options.handler();\n this.called += 1;\n }, this.options.duration);\n }\n}\n\n$interval[KIND] = IntervalPrimitive;\n","import { createMiddleware, type Middleware } from \"alepha\";\nimport {\n DateTimeProvider,\n type DurationLike,\n} from \"../providers/DateTimeProvider.ts\";\n\nexport interface DebounceOptions {\n /**\n * Coalescing window. Concurrent calls within this window share one execution.\n */\n delay: DurationLike;\n\n /**\n * Key function to group calls. Calls with the same key are coalesced.\n * Defaults to `JSON.stringify(args)`.\n */\n key?: (...args: any[]) => string;\n}\n\n/**\n * Middleware that coalesces concurrent calls with the same key into a single handler execution.\n *\n * All callers within the delay window receive the same result. No storage —\n * once the handler finishes, the next call starts fresh. Process-local.\n *\n * **Use case**: thundering herd protection — cache expires, 100 requests\n * hit the same endpoint, debounce ensures one rebuild.\n *\n * ```typescript\n * class SearchController {\n * search = $action({\n * use: [$debounce({ delay: [200, \"ms\"], key: (req) => req.query.q })],\n * handler: async ({ query }) => this.searchService.search(query.q),\n * });\n * }\n * ```\n */\nexport const $debounce = (options: DebounceOptions): Middleware => {\n return createMiddleware({\n name: \"$debounce\",\n options: options as unknown as Record<string, unknown>,\n handler: ({ alepha, next }) => {\n const dateTimeProvider = alepha.inject(DateTimeProvider);\n const pending = new Map<string, Promise<any>>();\n\n return async (...args) => {\n const key = options.key?.(...args) ?? JSON.stringify(args);\n\n const existing = pending.get(key);\n if (existing) {\n return existing;\n }\n\n let resolve: (value: any) => void;\n let reject: (error: any) => void;\n const promise = new Promise<any>((res, rej) => {\n resolve = res;\n reject = rej;\n });\n\n dateTimeProvider.createTimeout(async () => {\n try {\n const result = await next(...args);\n resolve!(result);\n } catch (error) {\n reject!(error);\n } finally {\n pending.delete(key);\n }\n }, options.delay);\n\n pending.set(key, promise);\n return promise;\n };\n },\n });\n};\n","import { createMiddleware, type Middleware } from \"alepha\";\nimport {\n DateTimeProvider,\n type DurationLike,\n} from \"../providers/DateTimeProvider.ts\";\n\nexport interface ThrottleOptions {\n /**\n * Max calls per window.\n */\n rate: number;\n\n /**\n * Window duration.\n */\n per: DurationLike;\n}\n\n/**\n * Middleware that rate-controls handler execution using a token bucket.\n *\n * Excess calls are **delayed** until capacity is available — never rejected.\n * Process-local (not distributed). Use `$rateLimit` for distributed rate limiting.\n *\n * **Use case**: protect an external API from your own traffic.\n *\n * ```typescript\n * class PaymentController {\n * charge = $action({\n * use: [$throttle({ rate: 80, per: [1, \"second\"] })],\n * handler: async ({ body }) => this.stripe.charges.create(body),\n * });\n * }\n * ```\n */\nexport const $throttle = (options: ThrottleOptions): Middleware => {\n return createMiddleware({\n name: \"$throttle\",\n options: options as unknown as Record<string, unknown>,\n handler: ({ alepha, next }) => {\n const dateTimeProvider = alepha.inject(DateTimeProvider);\n const intervalMs = dateTimeProvider\n .duration(options.per)\n .asMilliseconds();\n\n let tokens = options.rate;\n let lastRefill = dateTimeProvider.nowMillis();\n\n return async (...args) => {\n const now = dateTimeProvider.nowMillis();\n const elapsed = now - lastRefill;\n const refill = Math.floor(elapsed / intervalMs) * options.rate;\n\n if (refill > 0) {\n tokens = Math.min(options.rate, tokens + refill);\n lastRefill += Math.floor(elapsed / intervalMs) * intervalMs;\n }\n\n if (tokens <= 0) {\n const waitMs = intervalMs - (now - lastRefill);\n await dateTimeProvider.wait(waitMs);\n tokens = options.rate;\n lastRefill = dateTimeProvider.nowMillis();\n }\n\n tokens--;\n return next(...args);\n };\n },\n });\n};\n","import { AlephaError, createMiddleware, type Middleware } from \"alepha\";\nimport {\n DateTimeProvider,\n type DurationLike,\n} from \"../providers/DateTimeProvider.ts\";\n\n/**\n * Middleware that aborts handler execution if it exceeds a duration limit.\n *\n * Uses `Promise.race` with a managed timeout from `DateTimeProvider` —\n * if the handler doesn't resolve before the deadline, the promise rejects.\n * Uses managed timeouts so it works with `DateTimeProvider.travel()` in tests.\n *\n * ```typescript\n * class OrderService {\n * processOrder = $pipeline({\n * use: [$timeout([30, \"seconds\"])],\n * handler: async (orderId: string) => {\n * return await this.orders.updateById(orderId, { status: \"paid\" });\n * },\n * });\n * }\n * ```\n */\nexport const $timeout = (duration: DurationLike): Middleware => {\n return createMiddleware({\n name: \"$timeout\",\n options: { duration },\n handler: ({ alepha, next }) => {\n const dateTimeProvider = alepha.inject(DateTimeProvider);\n\n return async (...args) => {\n let rejectTimeout: (reason: Error) => void;\n const timeoutPromise = new Promise<never>((_, reject) => {\n rejectTimeout = reject;\n });\n\n const timer = dateTimeProvider.createTimeout(() => {\n rejectTimeout(new AlephaError(\"$timeout: handler exceeded deadline\"));\n }, duration);\n\n try {\n return await Promise.race([next(...args), timeoutPromise]);\n } finally {\n dateTimeProvider.clearTimeout(timer);\n }\n };\n },\n });\n};\n","import { $module } from \"alepha\";\nimport { $interval } from \"./primitives/$interval.ts\";\nimport { DateTimeProvider } from \"./providers/DateTimeProvider.ts\";\n\nexport * from \"./primitives/$debounce.ts\";\nexport * from \"./primitives/$interval.ts\";\nexport * from \"./primitives/$throttle.ts\";\nexport * from \"./primitives/$timeout.ts\";\nexport * from \"./providers/DateTimeProvider.ts\";\n\n// ---------------------------------------------------------------------------------------------------------------------\n\n/**\n * Date and time operations.\n *\n * **Features:**\n * - Recurring interval definitions\n * - Duration parsing (ISO 8601, human-readable)\n * - Timezone support\n * - Dayjs integration\n *\n * @module alepha.datetime\n */\nexport const AlephaDateTime = $module({\n name: \"alepha.datetime\",\n primitives: [$interval],\n services: [DateTimeProvider],\n});\n"],"mappings":"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"}
|