@gostack-framework/react 0.0.0-stage → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/api.d.ts +83 -0
- package/dist/api.js +170 -0
- package/dist/api.js.map +1 -0
- package/dist/auth.d.ts +60 -0
- package/dist/auth.js +136 -0
- package/dist/auth.js.map +1 -0
- package/dist/data.d.ts +25 -0
- package/dist/data.js +73 -0
- package/dist/data.js.map +1 -0
- package/dist/examples.d.ts +6 -0
- package/dist/examples.js +47 -0
- package/dist/examples.js.map +1 -0
- package/dist/hooks.d.ts +58 -0
- package/dist/hooks.js +109 -0
- package/dist/hooks.js.map +1 -0
- package/dist/index.d.ts +20 -0
- package/dist/index.js +21 -0
- package/dist/index.js.map +1 -0
- package/dist/layouts.d.ts +6 -0
- package/dist/layouts.js +34 -0
- package/dist/layouts.js.map +1 -0
- package/dist/line-flow/bus.d.ts +13 -0
- package/dist/line-flow/bus.js +52 -0
- package/dist/line-flow/bus.js.map +1 -0
- package/dist/line-flow/derived-line.d.ts +21 -0
- package/dist/line-flow/derived-line.js +122 -0
- package/dist/line-flow/derived-line.js.map +1 -0
- package/dist/line-flow/errors.d.ts +62 -0
- package/dist/line-flow/errors.js +91 -0
- package/dist/line-flow/errors.js.map +1 -0
- package/dist/line-flow/event-line.d.ts +16 -0
- package/dist/line-flow/event-line.js +81 -0
- package/dist/line-flow/event-line.js.map +1 -0
- package/dist/line-flow/index.d.ts +11 -0
- package/dist/line-flow/index.js +11 -0
- package/dist/line-flow/index.js.map +1 -0
- package/dist/line-flow/interchange.d.ts +17 -0
- package/dist/line-flow/interchange.js +86 -0
- package/dist/line-flow/interchange.js.map +1 -0
- package/dist/line-flow/lineflow.d.ts +12 -0
- package/dist/line-flow/lineflow.js +15 -0
- package/dist/line-flow/lineflow.js.map +1 -0
- package/dist/line-flow/network.d.ts +28 -0
- package/dist/line-flow/network.js +165 -0
- package/dist/line-flow/network.js.map +1 -0
- package/dist/line-flow/react/bridge.d.ts +23 -0
- package/dist/line-flow/react/bridge.js +40 -0
- package/dist/line-flow/react/bridge.js.map +1 -0
- package/dist/line-flow/react/hooks.d.ts +29 -0
- package/dist/line-flow/react/hooks.js +117 -0
- package/dist/line-flow/react/hooks.js.map +1 -0
- package/dist/line-flow/react/index.d.ts +3 -0
- package/dist/line-flow/react/index.js +4 -0
- package/dist/line-flow/react/index.js.map +1 -0
- package/dist/line-flow/react/provider.d.ts +15 -0
- package/dist/line-flow/react/provider.js +25 -0
- package/dist/line-flow/react/provider.js.map +1 -0
- package/dist/line-flow/scope.d.ts +21 -0
- package/dist/line-flow/scope.js +157 -0
- package/dist/line-flow/scope.js.map +1 -0
- package/dist/line-flow/state-line.d.ts +21 -0
- package/dist/line-flow/state-line.js +106 -0
- package/dist/line-flow/state-line.js.map +1 -0
- package/dist/line-flow/taxi.d.ts +15 -0
- package/dist/line-flow/taxi.js +81 -0
- package/dist/line-flow/taxi.js.map +1 -0
- package/dist/line-flow/types.d.ts +222 -0
- package/dist/line-flow/types.js +2 -0
- package/dist/line-flow/types.js.map +1 -0
- package/dist/line-flow/utils.d.ts +24 -0
- package/dist/line-flow/utils.js +53 -0
- package/dist/line-flow/utils.js.map +1 -0
- package/dist/paramsSerializer.d.ts +87 -0
- package/dist/paramsSerializer.js +138 -0
- package/dist/paramsSerializer.js.map +1 -0
- package/dist/registry.d.ts +10 -0
- package/dist/registry.js +115 -0
- package/dist/registry.js.map +1 -0
- package/dist/runtime.d.ts +80 -0
- package/dist/runtime.js +442 -0
- package/dist/runtime.js.map +1 -0
- package/dist/schemas.d.ts +88 -0
- package/dist/schemas.js +146 -0
- package/dist/schemas.js.map +1 -0
- package/dist/services.d.ts +35 -0
- package/dist/services.js +65 -0
- package/dist/services.js.map +1 -0
- package/dist/shared-types/file.types.d.ts +12 -0
- package/dist/shared-types/file.types.js +2 -0
- package/dist/shared-types/file.types.js.map +1 -0
- package/dist/shared-types/gallery.types.d.ts +22 -0
- package/dist/shared-types/gallery.types.js +2 -0
- package/dist/shared-types/gallery.types.js.map +1 -0
- package/dist/shared-types/governorates.types.d.ts +12 -0
- package/dist/shared-types/governorates.types.js +2 -0
- package/dist/shared-types/governorates.types.js.map +1 -0
- package/dist/shared-types/grade.types.d.ts +7 -0
- package/dist/shared-types/grade.types.js +2 -0
- package/dist/shared-types/grade.types.js.map +1 -0
- package/dist/shared-types/index.d.ts +13 -0
- package/dist/shared-types/index.js +14 -0
- package/dist/shared-types/index.js.map +1 -0
- package/dist/shared-types/metadata.types.d.ts +61 -0
- package/dist/shared-types/metadata.types.js +3 -0
- package/dist/shared-types/metadata.types.js.map +1 -0
- package/dist/shared-types/table.types.d.ts +33 -0
- package/dist/shared-types/table.types.js +2 -0
- package/dist/shared-types/table.types.js.map +1 -0
- package/dist/shared-types/viewCard.types.d.ts +78 -0
- package/dist/shared-types/viewCard.types.js +3 -0
- package/dist/shared-types/viewCard.types.js.map +1 -0
- package/dist/styles.css +347 -0
- package/dist/types.d.ts +126 -0
- package/dist/types.js +19 -0
- package/dist/types.js.map +1 -0
- package/dist/utils/conditionCompiler.d.ts +11 -0
- package/dist/utils/conditionCompiler.js +18 -0
- package/dist/utils/conditionCompiler.js.map +1 -0
- package/dist/utils/fileUtils.d.ts +50 -0
- package/dist/utils/fileUtils.js +266 -0
- package/dist/utils/fileUtils.js.map +1 -0
- package/dist/utils/metadataUtils.d.ts +35 -0
- package/dist/utils/metadataUtils.js +176 -0
- package/dist/utils/metadataUtils.js.map +1 -0
- package/dist/utils/normalizeTime.d.ts +1 -0
- package/dist/utils/normalizeTime.js +25 -0
- package/dist/utils/normalizeTime.js.map +1 -0
- package/dist/utils/tableUtils.d.ts +9 -0
- package/dist/utils/tableUtils.js +92 -0
- package/dist/utils/tableUtils.js.map +1 -0
- package/dist/utils/toFormData.d.ts +152 -0
- package/dist/utils/toFormData.js +250 -0
- package/dist/utils/toFormData.js.map +1 -0
- package/dist/utils/wizard.utils.d.ts +420 -0
- package/dist/utils/wizard.utils.js +596 -0
- package/dist/utils/wizard.utils.js.map +1 -0
- package/package.json +49 -3
- package/README.md +0 -3
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"taxi.js","sourceRoot":"","sources":["../../src/line-flow/taxi.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,222 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Supported line kinds.
|
|
3
|
+
*/
|
|
4
|
+
export type LineKind = "state" | "event" | "derived";
|
|
5
|
+
/**
|
|
6
|
+
* Equality comparison function.
|
|
7
|
+
*/
|
|
8
|
+
export type EqualityFn<T> = (prev: T, next: T) => boolean;
|
|
9
|
+
/**
|
|
10
|
+
* Function invoked to cancel an active subscription or unregister a resource.
|
|
11
|
+
*/
|
|
12
|
+
export type Unsubscribe = () => void;
|
|
13
|
+
/**
|
|
14
|
+
* Listener function called with state updates or published events.
|
|
15
|
+
*/
|
|
16
|
+
export type Listener<T> = (value: T) => void;
|
|
17
|
+
/**
|
|
18
|
+
* A resource or function that can be disposed of.
|
|
19
|
+
*/
|
|
20
|
+
export type Disposable = {
|
|
21
|
+
dispose: () => void;
|
|
22
|
+
} | (() => void);
|
|
23
|
+
/**
|
|
24
|
+
* Base read-only interface implemented by lines that retain a snapshot (StateLine and DerivedLine).
|
|
25
|
+
*/
|
|
26
|
+
export interface ReadableLine<T> {
|
|
27
|
+
readonly id: string;
|
|
28
|
+
readonly kind: "state" | "derived";
|
|
29
|
+
getSnapshot(): T;
|
|
30
|
+
subscribe(listener: Listener<T>): Unsubscribe;
|
|
31
|
+
dispose(): void;
|
|
32
|
+
readonly isDisposed: boolean;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* A persistent state line.
|
|
36
|
+
*/
|
|
37
|
+
export interface StateLine<T> extends ReadableLine<T> {
|
|
38
|
+
readonly kind: "state";
|
|
39
|
+
set(value: T): void;
|
|
40
|
+
update(updater: (prev: T) => T): void;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* An ephemeral event line.
|
|
44
|
+
*/
|
|
45
|
+
export interface EventLine<T> {
|
|
46
|
+
readonly id: string;
|
|
47
|
+
readonly kind: "event";
|
|
48
|
+
publish(event: T): void;
|
|
49
|
+
subscribe(listener: Listener<T>): Unsubscribe;
|
|
50
|
+
dispose(): void;
|
|
51
|
+
readonly isDisposed: boolean;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Any line that retains a snapshot and allows reading and subscriptions.
|
|
55
|
+
*/
|
|
56
|
+
export type AnyStateLine = ReadableLine<any>;
|
|
57
|
+
/**
|
|
58
|
+
* Any line registered in the LineFlow network.
|
|
59
|
+
*/
|
|
60
|
+
export type AnyLine = StateLine<any> | EventLine<any> | DerivedLine<any>;
|
|
61
|
+
/**
|
|
62
|
+
* Extracts the snapshot value type from a readable line.
|
|
63
|
+
*/
|
|
64
|
+
export type LineSnapshot<TLine> = TLine extends ReadableLine<infer T> ? T : never;
|
|
65
|
+
/**
|
|
66
|
+
* Extracts a tuple of snapshot value types from a tuple/array of readable lines.
|
|
67
|
+
*/
|
|
68
|
+
export type LinesSnapshots<TLines extends readonly AnyStateLine[]> = {
|
|
69
|
+
readonly [K in keyof TLines]: LineSnapshot<TLines[K]>;
|
|
70
|
+
};
|
|
71
|
+
/**
|
|
72
|
+
* A read-only derived line whose snapshot is computed from one or more source lines.
|
|
73
|
+
*/
|
|
74
|
+
export interface DerivedLine<T> extends ReadableLine<T> {
|
|
75
|
+
readonly kind: "derived";
|
|
76
|
+
readonly sources: readonly AnyStateLine[];
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Options for creating a StateLine.
|
|
80
|
+
*/
|
|
81
|
+
export interface StateLineOptions<T> {
|
|
82
|
+
id: string;
|
|
83
|
+
initialValue: T;
|
|
84
|
+
equals?: EqualityFn<T> | undefined;
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Options for creating an EventLine.
|
|
88
|
+
*/
|
|
89
|
+
export interface EventLineOptions<T = void> {
|
|
90
|
+
id: string;
|
|
91
|
+
_phantom?: ((value: T) => void) | undefined;
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Options for creating a DerivedLine.
|
|
95
|
+
*/
|
|
96
|
+
export interface DeriveLineOptions<T, TDeps extends readonly AnyStateLine[]> {
|
|
97
|
+
id: string;
|
|
98
|
+
sources: TDeps;
|
|
99
|
+
derive: (snapshots: LinesSnapshots<TDeps>) => T;
|
|
100
|
+
equals?: EqualityFn<T> | undefined;
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Options for creating an Interchange between two state lines.
|
|
104
|
+
*/
|
|
105
|
+
export interface InterchangeOptions<TSource, TTarget> {
|
|
106
|
+
id?: string | undefined;
|
|
107
|
+
from: ReadableLine<TSource>;
|
|
108
|
+
to: StateLine<TTarget>;
|
|
109
|
+
transform: (sourceSnapshot: TSource) => TTarget;
|
|
110
|
+
equals?: EqualityFn<TTarget> | undefined;
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* Represents an active directional relationship between lines.
|
|
114
|
+
*/
|
|
115
|
+
export interface Interchange {
|
|
116
|
+
readonly id: string;
|
|
117
|
+
readonly isDisposed: boolean;
|
|
118
|
+
dispose(): void;
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* Feature-scoped message bus.
|
|
122
|
+
*/
|
|
123
|
+
export interface Bus<TMessageMap extends object = Record<string, unknown>> {
|
|
124
|
+
readonly id: string;
|
|
125
|
+
readonly isDisposed: boolean;
|
|
126
|
+
publish<K extends keyof TMessageMap & string>(channel: K, payload: TMessageMap[K]): void;
|
|
127
|
+
subscribe<K extends keyof TMessageMap & string>(channel: K, listener: (payload: TMessageMap[K]) => void): Unsubscribe;
|
|
128
|
+
dispose(): void;
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* Options for creating a Bus.
|
|
132
|
+
*/
|
|
133
|
+
export interface BusOptions {
|
|
134
|
+
id?: string | undefined;
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* Handler for a Taxi task.
|
|
138
|
+
*/
|
|
139
|
+
export type TaxiHandler<TReq, TRes> = (req: TReq, signal?: AbortSignal | undefined) => Promise<TRes> | TRes;
|
|
140
|
+
/**
|
|
141
|
+
* Single task request/response contract.
|
|
142
|
+
*/
|
|
143
|
+
export interface TaskContract<TRequest = any, TResponse = any> {
|
|
144
|
+
request: TRequest;
|
|
145
|
+
response: TResponse;
|
|
146
|
+
}
|
|
147
|
+
/**
|
|
148
|
+
* Taxi task contract map.
|
|
149
|
+
*/
|
|
150
|
+
export type TaxiTaskMap = Record<string, TaskContract>;
|
|
151
|
+
/**
|
|
152
|
+
* Typed request/response handler service.
|
|
153
|
+
*/
|
|
154
|
+
export interface Taxi<TTaskMap extends {
|
|
155
|
+
[K in keyof TTaskMap]: TaskContract;
|
|
156
|
+
} = TaxiTaskMap> {
|
|
157
|
+
readonly id: string;
|
|
158
|
+
readonly isDisposed: boolean;
|
|
159
|
+
register<K extends keyof TTaskMap & string>(task: K, handler: TaxiHandler<TTaskMap[K]["request"], TTaskMap[K]["response"]>): Unsubscribe;
|
|
160
|
+
request<K extends keyof TTaskMap & string>(task: K, req: TTaskMap[K]["request"], options?: {
|
|
161
|
+
signal?: AbortSignal | undefined;
|
|
162
|
+
} | undefined): Promise<TTaskMap[K]["response"]>;
|
|
163
|
+
hasHandler<K extends keyof TTaskMap & string>(task: K): boolean;
|
|
164
|
+
dispose(): void;
|
|
165
|
+
}
|
|
166
|
+
/**
|
|
167
|
+
* Options for creating a Taxi.
|
|
168
|
+
*/
|
|
169
|
+
export interface TaxiOptions {
|
|
170
|
+
id?: string | undefined;
|
|
171
|
+
}
|
|
172
|
+
/**
|
|
173
|
+
* Scoped lifecycle boundary for managing lines and resources.
|
|
174
|
+
*/
|
|
175
|
+
export interface Scope {
|
|
176
|
+
readonly id: string;
|
|
177
|
+
readonly isDisposed: boolean;
|
|
178
|
+
registerDisposable(disposable: Disposable): Unsubscribe;
|
|
179
|
+
stateLine<T>(options: StateLineOptions<T>): StateLine<T>;
|
|
180
|
+
eventLine<T = void>(options: EventLineOptions<T>): EventLine<T>;
|
|
181
|
+
deriveLine<T, const TDeps extends readonly AnyStateLine[]>(options: DeriveLineOptions<T, TDeps>): DerivedLine<T>;
|
|
182
|
+
bus<TMessageMap extends object = Record<string, unknown>>(options?: BusOptions): Bus<TMessageMap>;
|
|
183
|
+
taxi<TTaskMap extends {
|
|
184
|
+
[K in keyof TTaskMap]: TaskContract;
|
|
185
|
+
} = TaxiTaskMap>(options?: TaxiOptions): Taxi<TTaskMap>;
|
|
186
|
+
createChildScope(id: string): Scope;
|
|
187
|
+
dispose(): void;
|
|
188
|
+
}
|
|
189
|
+
/**
|
|
190
|
+
* Options for creating a Scope.
|
|
191
|
+
*/
|
|
192
|
+
export interface ScopeOptions {
|
|
193
|
+
id?: string | undefined;
|
|
194
|
+
}
|
|
195
|
+
/**
|
|
196
|
+
* Network instance options.
|
|
197
|
+
*/
|
|
198
|
+
export interface LineFlowOptions {
|
|
199
|
+
name?: string | undefined;
|
|
200
|
+
}
|
|
201
|
+
/**
|
|
202
|
+
* The runtime LineFlow network owning lines and registries.
|
|
203
|
+
*/
|
|
204
|
+
export interface LineFlowNetwork {
|
|
205
|
+
readonly name: string;
|
|
206
|
+
readonly isDisposed: boolean;
|
|
207
|
+
stateLine<T>(options: StateLineOptions<T>): StateLine<T>;
|
|
208
|
+
eventLine<T = void>(options: EventLineOptions<T>): EventLine<T>;
|
|
209
|
+
deriveLine<T, const TDeps extends readonly AnyStateLine[]>(options: DeriveLineOptions<T, TDeps>): DerivedLine<T>;
|
|
210
|
+
createInterchange<TSource, TTarget>(options: InterchangeOptions<TSource, TTarget>): Interchange;
|
|
211
|
+
createScope(options?: ScopeOptions): Scope;
|
|
212
|
+
bus<TMessageMap extends object = Record<string, unknown>>(options?: BusOptions): Bus<TMessageMap>;
|
|
213
|
+
taxi<TTaskMap extends {
|
|
214
|
+
[K in keyof TTaskMap]: TaskContract;
|
|
215
|
+
} = TaxiTaskMap>(options?: TaxiOptions): Taxi<TTaskMap>;
|
|
216
|
+
getLine(id: string): AnyLine | undefined;
|
|
217
|
+
hasLine(id: string): boolean;
|
|
218
|
+
getAllLines(): readonly AnyLine[];
|
|
219
|
+
dispose(): void;
|
|
220
|
+
}
|
|
221
|
+
export type LineflowOptions = LineFlowOptions;
|
|
222
|
+
export type LineflowNetwork = LineFlowNetwork;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/line-flow/types.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { EqualityFn, Listener } from "./types.js";
|
|
2
|
+
/**
|
|
3
|
+
* Validates that an ID is a non-empty string.
|
|
4
|
+
*/
|
|
5
|
+
export declare function validateId(id: unknown, context?: string): string;
|
|
6
|
+
/**
|
|
7
|
+
* Validates that a listener is a function.
|
|
8
|
+
*/
|
|
9
|
+
export declare function validateListener(listener: unknown): asserts listener is (arg: any) => void;
|
|
10
|
+
/**
|
|
11
|
+
* Default equality function using Object.is.
|
|
12
|
+
*/
|
|
13
|
+
export declare const defaultEquals: EqualityFn<any>;
|
|
14
|
+
/**
|
|
15
|
+
* Safely dispatches a value to a set of listeners.
|
|
16
|
+
*
|
|
17
|
+
* Guarantees:
|
|
18
|
+
* 1. Subscribers receive notifications in order of registration.
|
|
19
|
+
* 2. Unsubscribing a listener during dispatch takes effect immediately for that tick.
|
|
20
|
+
* 3. Adding a new listener during dispatch does not invoke it during the current tick.
|
|
21
|
+
* 4. If any listener throws an error, all other eligible listeners are still executed.
|
|
22
|
+
* 5. All thrown errors are collected and raised in a single LineFlowSubscriberError.
|
|
23
|
+
*/
|
|
24
|
+
export declare function notifyListeners<T>(listeners: ReadonlySet<Listener<T>>, value: T, contextDescription: string): void;
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { LineFlowSubscriberError, LineFlowValidationError } from "./errors.js";
|
|
2
|
+
/**
|
|
3
|
+
* Validates that an ID is a non-empty string.
|
|
4
|
+
*/
|
|
5
|
+
export function validateId(id, context = "line") {
|
|
6
|
+
if (typeof id !== "string" || id.trim().length === 0) {
|
|
7
|
+
throw new LineFlowValidationError(`Invalid ${context} ID: expected a non-empty string, but received ${String(id)}.`);
|
|
8
|
+
}
|
|
9
|
+
return id;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Validates that a listener is a function.
|
|
13
|
+
*/
|
|
14
|
+
export function validateListener(listener) {
|
|
15
|
+
if (typeof listener !== "function") {
|
|
16
|
+
throw new LineFlowValidationError(`Invalid listener: expected a function, but received ${typeof listener}.`);
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Default equality function using Object.is.
|
|
21
|
+
*/
|
|
22
|
+
export const defaultEquals = (a, b) => Object.is(a, b);
|
|
23
|
+
/**
|
|
24
|
+
* Safely dispatches a value to a set of listeners.
|
|
25
|
+
*
|
|
26
|
+
* Guarantees:
|
|
27
|
+
* 1. Subscribers receive notifications in order of registration.
|
|
28
|
+
* 2. Unsubscribing a listener during dispatch takes effect immediately for that tick.
|
|
29
|
+
* 3. Adding a new listener during dispatch does not invoke it during the current tick.
|
|
30
|
+
* 4. If any listener throws an error, all other eligible listeners are still executed.
|
|
31
|
+
* 5. All thrown errors are collected and raised in a single LineFlowSubscriberError.
|
|
32
|
+
*/
|
|
33
|
+
export function notifyListeners(listeners, value, contextDescription) {
|
|
34
|
+
if (listeners.size === 0)
|
|
35
|
+
return;
|
|
36
|
+
const errors = [];
|
|
37
|
+
const snapshot = Array.from(listeners);
|
|
38
|
+
for (const listener of snapshot) {
|
|
39
|
+
if (!listeners.has(listener)) {
|
|
40
|
+
continue;
|
|
41
|
+
}
|
|
42
|
+
try {
|
|
43
|
+
listener(value);
|
|
44
|
+
}
|
|
45
|
+
catch (err) {
|
|
46
|
+
errors.push(err);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
if (errors.length > 0) {
|
|
50
|
+
throw new LineFlowSubscriberError(`Error(s) encountered in subscriber(s) during ${contextDescription}`, errors);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
//# sourceMappingURL=utils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../../src/line-flow/utils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,uBAAuB,EAAE,uBAAuB,EAAE,MAAM,aAAa,CAAC;AAG/E;;GAEG;AACH,MAAM,UAAU,UAAU,CAAC,EAAW,EAAE,OAAO,GAAG,MAAM;IACtD,IAAI,OAAO,EAAE,KAAK,QAAQ,IAAI,EAAE,CAAC,IAAI,EAAE,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACrD,MAAM,IAAI,uBAAuB,CAC/B,WAAW,OAAO,kDAAkD,MAAM,CAAC,EAAE,CAAC,GAAG,CAClF,CAAC;IACJ,CAAC;IACD,OAAO,EAAE,CAAC;AACZ,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,gBAAgB,CAAC,QAAiB;IAChD,IAAI,OAAO,QAAQ,KAAK,UAAU,EAAE,CAAC;QACnC,MAAM,IAAI,uBAAuB,CAC/B,uDAAuD,OAAO,QAAQ,GAAG,CAC1E,CAAC;IACJ,CAAC;AACH,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,MAAM,aAAa,GAAoB,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;AAExE;;;;;;;;;GASG;AACH,MAAM,UAAU,eAAe,CAC7B,SAAmC,EACnC,KAAQ,EACR,kBAA0B;IAE1B,IAAI,SAAS,CAAC,IAAI,KAAK,CAAC;QAAE,OAAO;IAEjC,MAAM,MAAM,GAAc,EAAE,CAAC;IAC7B,MAAM,QAAQ,GAAG,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IAEvC,KAAK,MAAM,QAAQ,IAAI,QAAQ,EAAE,CAAC;QAChC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC;YAC7B,SAAS;QACX,CAAC;QACD,IAAI,CAAC;YACH,QAAQ,CAAC,KAAK,CAAC,CAAC;QAClB,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACnB,CAAC;IACH,CAAC;IAED,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACtB,MAAM,IAAI,uBAAuB,CAC/B,gDAAgD,kBAAkB,EAAE,EACpE,MAAM,CACP,CAAC;IACJ,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Advanced Params Serializer
|
|
3
|
+
*
|
|
4
|
+
* Serializes complex query parameters including:
|
|
5
|
+
* - Nested objects: filters[status]=active
|
|
6
|
+
* - Arrays: ids[]=1&ids[]=2
|
|
7
|
+
* - Sort objects: sort[field]=name&sort[order]=asc
|
|
8
|
+
* - Pagination: page=1&per_page=10
|
|
9
|
+
* - Date ranges: date[from]=2024-01-01&date[to]=2024-12-31
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* ```ts
|
|
13
|
+
* serializeParams({
|
|
14
|
+
* page: 1,
|
|
15
|
+
* filters: { status: 'active', types: ['a', 'b'] },
|
|
16
|
+
* sort: { field: 'name', order: 'asc' }
|
|
17
|
+
* });
|
|
18
|
+
* // Returns: "page=1&filters[status]=active&filters[types][]=a&filters[types][]=b&sort[field]=name&sort[order]=asc"
|
|
19
|
+
* ```
|
|
20
|
+
*/
|
|
21
|
+
export type ParamValue = string | number | boolean | null | undefined | Date | ParamValue[] | {
|
|
22
|
+
[key: string]: ParamValue;
|
|
23
|
+
};
|
|
24
|
+
export interface SerializerOptions {
|
|
25
|
+
/**
|
|
26
|
+
* Array format: 'brackets' for key[]=value, 'indices' for key[0]=value, 'repeat' for key=value&key=value
|
|
27
|
+
* @default 'brackets'
|
|
28
|
+
*/
|
|
29
|
+
arrayFormat?: "brackets" | "indices" | "repeat";
|
|
30
|
+
/**
|
|
31
|
+
* Whether to encode keys and values
|
|
32
|
+
* @default true
|
|
33
|
+
*/
|
|
34
|
+
encode?: boolean;
|
|
35
|
+
/**
|
|
36
|
+
* Whether to skip null/undefined values
|
|
37
|
+
* @default true
|
|
38
|
+
*/
|
|
39
|
+
skipNull?: boolean;
|
|
40
|
+
/**
|
|
41
|
+
* Whether to skip empty strings
|
|
42
|
+
* @default true
|
|
43
|
+
*/
|
|
44
|
+
skipEmpty?: boolean;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Serialize an object of parameters into a query string
|
|
48
|
+
*
|
|
49
|
+
* @param params - The parameters object to serialize
|
|
50
|
+
* @param options - Serialization options
|
|
51
|
+
* @returns The serialized query string (without leading ?)
|
|
52
|
+
*/
|
|
53
|
+
export declare const serializeParams: (params?: Record<string, ParamValue>, options?: SerializerOptions) => string;
|
|
54
|
+
/**
|
|
55
|
+
* Create an Axios-compatible params serializer function
|
|
56
|
+
*/
|
|
57
|
+
export declare const createParamsSerializer: (options?: SerializerOptions) => (params: Record<string, ParamValue>) => string;
|
|
58
|
+
/**
|
|
59
|
+
* Standard pagination params interface
|
|
60
|
+
*/
|
|
61
|
+
export interface PaginationParams {
|
|
62
|
+
page?: number;
|
|
63
|
+
perPage?: number;
|
|
64
|
+
per_page?: number;
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Standard sort params interface
|
|
68
|
+
*/
|
|
69
|
+
export interface SortParams {
|
|
70
|
+
sortBy?: string;
|
|
71
|
+
sortOrder?: "asc" | "desc";
|
|
72
|
+
sort?: {
|
|
73
|
+
field?: string;
|
|
74
|
+
order?: "asc" | "desc";
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Standard filter params interface (generic)
|
|
79
|
+
*/
|
|
80
|
+
export interface FilterParams<T = Record<string, ParamValue>> {
|
|
81
|
+
filters?: T;
|
|
82
|
+
search?: string;
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Combined query params type for list endpoints
|
|
86
|
+
*/
|
|
87
|
+
export type ListQueryParams<TFilters = Record<string, ParamValue>> = PaginationParams & SortParams & FilterParams<TFilters>;
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Advanced Params Serializer
|
|
3
|
+
*
|
|
4
|
+
* Serializes complex query parameters including:
|
|
5
|
+
* - Nested objects: filters[status]=active
|
|
6
|
+
* - Arrays: ids[]=1&ids[]=2
|
|
7
|
+
* - Sort objects: sort[field]=name&sort[order]=asc
|
|
8
|
+
* - Pagination: page=1&per_page=10
|
|
9
|
+
* - Date ranges: date[from]=2024-01-01&date[to]=2024-12-31
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* ```ts
|
|
13
|
+
* serializeParams({
|
|
14
|
+
* page: 1,
|
|
15
|
+
* filters: { status: 'active', types: ['a', 'b'] },
|
|
16
|
+
* sort: { field: 'name', order: 'asc' }
|
|
17
|
+
* });
|
|
18
|
+
* // Returns: "page=1&filters[status]=active&filters[types][]=a&filters[types][]=b&sort[field]=name&sort[order]=asc"
|
|
19
|
+
* ```
|
|
20
|
+
*/
|
|
21
|
+
const defaultOptions = {
|
|
22
|
+
arrayFormat: "brackets",
|
|
23
|
+
encode: true,
|
|
24
|
+
skipNull: true,
|
|
25
|
+
skipEmpty: true,
|
|
26
|
+
};
|
|
27
|
+
/**
|
|
28
|
+
* Serialize a single value with proper encoding
|
|
29
|
+
*/
|
|
30
|
+
const encodeValue = (value, encode) => {
|
|
31
|
+
const stringValue = String(value);
|
|
32
|
+
if (!encode)
|
|
33
|
+
return stringValue;
|
|
34
|
+
return encodeURIComponent(stringValue)
|
|
35
|
+
.replace(/%3D/g, "=")
|
|
36
|
+
.replace(/%3E/g, ">")
|
|
37
|
+
.replace(/%3C/g, "<");
|
|
38
|
+
};
|
|
39
|
+
/**
|
|
40
|
+
* Serialize a key with proper encoding, keeping square brackets unencoded
|
|
41
|
+
*/
|
|
42
|
+
const encodeKey = (key, encode) => {
|
|
43
|
+
if (!encode)
|
|
44
|
+
return key;
|
|
45
|
+
return encodeURIComponent(key).replace(/%5B/g, "[").replace(/%5D/g, "]");
|
|
46
|
+
};
|
|
47
|
+
/**
|
|
48
|
+
* Build a nested key path like "filters[status]" or "filters[types][]"
|
|
49
|
+
*/
|
|
50
|
+
const buildKey = (prefix, key, isArrayItem, arrayFormat, index) => {
|
|
51
|
+
if (!prefix) {
|
|
52
|
+
return key;
|
|
53
|
+
}
|
|
54
|
+
if (isArrayItem) {
|
|
55
|
+
switch (arrayFormat) {
|
|
56
|
+
case "indices":
|
|
57
|
+
return `${prefix}[${index}]`;
|
|
58
|
+
case "repeat":
|
|
59
|
+
return prefix;
|
|
60
|
+
case "brackets":
|
|
61
|
+
default:
|
|
62
|
+
return `${prefix}[]`;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
return `${prefix}[${key}]`;
|
|
66
|
+
};
|
|
67
|
+
/**
|
|
68
|
+
* Recursively serialize parameters with circular reference protection
|
|
69
|
+
*/
|
|
70
|
+
const serializeValue = (key, value, options, parts, seen = new WeakSet()) => {
|
|
71
|
+
// Skip null/undefined
|
|
72
|
+
if (value === null || value === undefined) {
|
|
73
|
+
if (!options.skipNull) {
|
|
74
|
+
parts.push(`${encodeKey(key, options.encode)}=`);
|
|
75
|
+
}
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
78
|
+
// Skip empty strings
|
|
79
|
+
if (value === "" && options.skipEmpty) {
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
82
|
+
// Handle Date objects
|
|
83
|
+
if (value instanceof Date) {
|
|
84
|
+
parts.push(`${encodeKey(key, options.encode)}=${encodeValue(value.toISOString(), options.encode)}`);
|
|
85
|
+
return;
|
|
86
|
+
}
|
|
87
|
+
// Handle arrays
|
|
88
|
+
if (Array.isArray(value)) {
|
|
89
|
+
value.forEach((item, index) => {
|
|
90
|
+
const arrayKey = buildKey(key, "", true, options.arrayFormat, index);
|
|
91
|
+
serializeValue(arrayKey, item, options, parts, seen);
|
|
92
|
+
});
|
|
93
|
+
return;
|
|
94
|
+
}
|
|
95
|
+
// Handle objects (nested params)
|
|
96
|
+
if (typeof value === "object") {
|
|
97
|
+
// Circular reference protection
|
|
98
|
+
if (seen.has(value)) {
|
|
99
|
+
console.warn(`[paramsSerializer] Circular reference detected for key "${key}", skipping`);
|
|
100
|
+
return;
|
|
101
|
+
}
|
|
102
|
+
seen.add(value);
|
|
103
|
+
Object.entries(value).forEach(([nestedKey, nestedValue]) => {
|
|
104
|
+
const fullKey = buildKey(key, nestedKey, false, options.arrayFormat);
|
|
105
|
+
serializeValue(fullKey, nestedValue, options, parts, seen);
|
|
106
|
+
});
|
|
107
|
+
return;
|
|
108
|
+
}
|
|
109
|
+
// Handle primitives (string, number, boolean)
|
|
110
|
+
parts.push(`${encodeKey(key, options.encode)}=${encodeValue(value, options.encode)}`);
|
|
111
|
+
};
|
|
112
|
+
/**
|
|
113
|
+
* Serialize an object of parameters into a query string
|
|
114
|
+
*
|
|
115
|
+
* @param params - The parameters object to serialize
|
|
116
|
+
* @param options - Serialization options
|
|
117
|
+
* @returns The serialized query string (without leading ?)
|
|
118
|
+
*/
|
|
119
|
+
export const serializeParams = (params, options) => {
|
|
120
|
+
if (!params || Object.keys(params).length === 0) {
|
|
121
|
+
return "";
|
|
122
|
+
}
|
|
123
|
+
const mergedOptions = { ...defaultOptions, ...options };
|
|
124
|
+
const parts = [];
|
|
125
|
+
Object.entries(params).forEach(([key, value]) => {
|
|
126
|
+
serializeValue(key, value, mergedOptions, parts);
|
|
127
|
+
});
|
|
128
|
+
return parts.join("&");
|
|
129
|
+
};
|
|
130
|
+
/**
|
|
131
|
+
* Create an Axios-compatible params serializer function
|
|
132
|
+
*/
|
|
133
|
+
export const createParamsSerializer = (options) => {
|
|
134
|
+
return (params) => {
|
|
135
|
+
return serializeParams(params, options);
|
|
136
|
+
};
|
|
137
|
+
};
|
|
138
|
+
//# sourceMappingURL=paramsSerializer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"paramsSerializer.js","sourceRoot":"","sources":["../src/paramsSerializer.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { Manifest, Registry } from "./types";
|
|
2
|
+
export declare const normalizePath: (value: string) => string;
|
|
3
|
+
export declare const joinPath: (...parts: string[]) => string;
|
|
4
|
+
export declare function createRegistry(manifest: Manifest, layouts: string[]): Registry;
|
|
5
|
+
export declare function createPaths(base: string): {
|
|
6
|
+
main: string;
|
|
7
|
+
create: () => string;
|
|
8
|
+
detail: (id: string | number) => string;
|
|
9
|
+
edit: (id: string | number) => string;
|
|
10
|
+
};
|
package/dist/registry.js
ADDED
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
export const normalizePath = (value) => "/" + value.split("/").filter(Boolean).join("/");
|
|
2
|
+
export const joinPath = (...parts) => normalizePath(parts.join("/"));
|
|
3
|
+
const ownerDir = (file) => file.replaceAll("\\", "/").replace(/\/navigation\/index\.[jt]sx?$/, "");
|
|
4
|
+
export function createRegistry(manifest, layouts) {
|
|
5
|
+
const modules = [];
|
|
6
|
+
const ids = new Set();
|
|
7
|
+
for (const { file, definition } of manifest.definitions) {
|
|
8
|
+
if (!definition || !["module", "feature"].includes(definition.kind))
|
|
9
|
+
throw new Error(`GoStack: ${file} must default-export defineModule() or defineFeature().`);
|
|
10
|
+
if (definition.kind !== "module")
|
|
11
|
+
continue;
|
|
12
|
+
if (ids.has(definition.id))
|
|
13
|
+
throw new Error(`GoStack: duplicate module "${definition.id}" in ${file}.`);
|
|
14
|
+
ids.add(definition.id);
|
|
15
|
+
if (!layouts.includes(definition.layout))
|
|
16
|
+
throw new Error(`GoStack: unknown layout "${definition.layout}" in ${file}. Available: ${layouts.join(", ")}.`);
|
|
17
|
+
modules.push({ dir: ownerDir(file), definition });
|
|
18
|
+
}
|
|
19
|
+
const features = [];
|
|
20
|
+
const disabledSources = [];
|
|
21
|
+
const featureIds = new Set();
|
|
22
|
+
const routePaths = new Map();
|
|
23
|
+
for (const { file, definition } of manifest.definitions) {
|
|
24
|
+
if (definition.kind !== "feature")
|
|
25
|
+
continue;
|
|
26
|
+
const dir = ownerDir(file);
|
|
27
|
+
const hierarchy = modules
|
|
28
|
+
.filter((m) => dir.startsWith(m.dir + "/"))
|
|
29
|
+
.sort((a, b) => a.dir.length - b.dir.length);
|
|
30
|
+
const parent = hierarchy.at(-1);
|
|
31
|
+
if (!parent)
|
|
32
|
+
throw new Error(`GoStack: feature ${file} has no containing module navigation/index.ts.`);
|
|
33
|
+
const qualifiedId = `${parent.definition.id}/${definition.id}`;
|
|
34
|
+
if (featureIds.has(qualifiedId))
|
|
35
|
+
throw new Error(`GoStack: duplicate feature "${qualifiedId}" in ${file}.`);
|
|
36
|
+
featureIds.add(qualifiedId);
|
|
37
|
+
const layout = definition.layout ?? parent.definition.layout;
|
|
38
|
+
if (!layouts.includes(layout))
|
|
39
|
+
throw new Error(`GoStack: unknown layout "${layout}" in ${file}.`);
|
|
40
|
+
if (definition.enabled === false ||
|
|
41
|
+
hierarchy.some((m) => m.definition.enabled === false)) {
|
|
42
|
+
disabledSources.push(dir);
|
|
43
|
+
continue;
|
|
44
|
+
}
|
|
45
|
+
const base = joinPath(parent.definition.basePath, definition.basePath);
|
|
46
|
+
const visit = (routes, prefix) => {
|
|
47
|
+
for (const route of routes) {
|
|
48
|
+
if (route.index && (route.path !== undefined || route.children))
|
|
49
|
+
throw new Error(`GoStack: index route cannot have path or children in ${file}.`);
|
|
50
|
+
if (route.path?.startsWith("/"))
|
|
51
|
+
throw new Error(`GoStack: feature routes must use relative paths in ${file}.`);
|
|
52
|
+
const full = joinPath(prefix, route.path ?? "");
|
|
53
|
+
if (!route.children?.length || route.index) {
|
|
54
|
+
const signature = full.replace(/:[^/]+/g, ":param").toLowerCase();
|
|
55
|
+
if (routePaths.has(signature))
|
|
56
|
+
throw new Error(`GoStack: conflicting route "${full}" in ${file} and ${routePaths.get(signature)}.`);
|
|
57
|
+
routePaths.set(signature, file);
|
|
58
|
+
}
|
|
59
|
+
if (route.children)
|
|
60
|
+
visit(route.children, full);
|
|
61
|
+
}
|
|
62
|
+
};
|
|
63
|
+
visit(definition.routes, base);
|
|
64
|
+
features.push({
|
|
65
|
+
...definition,
|
|
66
|
+
module: parent.definition,
|
|
67
|
+
ancestors: hierarchy.slice(0, -1).map((m) => m.definition),
|
|
68
|
+
qualifiedId,
|
|
69
|
+
namespace: qualifiedId.replaceAll("/", "."),
|
|
70
|
+
source: dir,
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
const resources = {};
|
|
74
|
+
for (const locale of manifest.locales) {
|
|
75
|
+
const file = locale.file.replaceAll("\\", "/");
|
|
76
|
+
if (disabledSources.some((dir) => file.startsWith(dir + "/")))
|
|
77
|
+
continue;
|
|
78
|
+
const match = file.match(/\/(?:locales|locals)\/([\w-]+)\.json$/);
|
|
79
|
+
if (!match)
|
|
80
|
+
continue;
|
|
81
|
+
const feature = features
|
|
82
|
+
.filter((f) => file.startsWith(f.source + "/"))
|
|
83
|
+
.sort((a, b) => b.source.length - a.source.length)[0];
|
|
84
|
+
const module = modules
|
|
85
|
+
.filter((m) => file.startsWith(m.dir + "/"))
|
|
86
|
+
.sort((a, b) => b.dir.length - a.dir.length)[0];
|
|
87
|
+
const namespace = feature?.namespace ??
|
|
88
|
+
(file.includes("/design-system/")
|
|
89
|
+
? "designSystem"
|
|
90
|
+
: module
|
|
91
|
+
? module.definition.id.replaceAll("/", ".")
|
|
92
|
+
: "shared");
|
|
93
|
+
const language = match[1];
|
|
94
|
+
resources[language] ??= {};
|
|
95
|
+
if (resources[language][namespace])
|
|
96
|
+
throw new Error(`GoStack: duplicate translation namespace "${namespace}" for ${language}: ${file}.`);
|
|
97
|
+
resources[language][namespace] = locale.data;
|
|
98
|
+
}
|
|
99
|
+
return {
|
|
100
|
+
modules: modules
|
|
101
|
+
.map((m) => m.definition)
|
|
102
|
+
.filter((m) => m.enabled !== false),
|
|
103
|
+
features,
|
|
104
|
+
resources,
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
export function createPaths(base) {
|
|
108
|
+
return {
|
|
109
|
+
main: normalizePath(base),
|
|
110
|
+
create: () => joinPath(base, "create"),
|
|
111
|
+
detail: (id) => joinPath(base, encodeURIComponent(String(id))),
|
|
112
|
+
edit: (id) => joinPath(base, encodeURIComponent(String(id)), "edit"),
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
//# sourceMappingURL=registry.js.map
|