akanjs 2.3.5-rc.5 → 2.3.5-rc.7
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/README.ko.md +44 -13
- package/README.md +43 -12
- package/constant/constantRegistry.ts +17 -117
- package/fetch/fetchType/buildFetch.type.ts +25 -18
- package/fetch/fetchType/endpointFetch.type.ts +49 -81
- package/fetch/fetchType/sliceFetch.type.ts +77 -147
- package/fetch/types.ts +17 -4
- package/package.json +1 -1
- package/signal/slice.ts +13 -15
- package/signal/sliceInfo.ts +8 -47
- package/types/constant/constantRegistry.d.ts +1 -39
- package/types/fetch/fetchType/buildFetch.type.d.ts +20 -8
- package/types/fetch/fetchType/endpointFetch.type.d.ts +16 -35
- package/types/fetch/fetchType/sliceFetch.type.d.ts +31 -66
- package/types/fetch/types.d.ts +9 -2
- package/types/signal/slice.d.ts +4 -4
- package/types/signal/sliceInfo.d.ts +3 -19
package/README.ko.md
CHANGED
|
@@ -2,12 +2,12 @@
|
|
|
2
2
|
|
|
3
3
|
[English](https://unpkg.com/akanjs@latest/README.md) | [Docs](https://akanjs.com/docs) | [npm](https://www.npmjs.com/package/akanjs)
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
**
|
|
5
|
+
**한 줄의 비즈니스 코드로 웹·iOS·Android·서버·DB를 한 번에.**
|
|
6
|
+
**One line of business code ships web, iOS, Android, server, and database together.**
|
|
7
7
|
|
|
8
|
-
Akan.js는 비즈니스
|
|
9
|
-
|
|
10
|
-
|
|
8
|
+
프레임워크 조립, 중복 선언, 플랫폼별 재작성은 이제 그만. Akan.js는 비즈니스 의도를 한 곳에 쓰면
|
|
9
|
+
SEO 웹, iOS/Android 앱 패키지, 서버, 데이터베이스 계약, 인프라 산출물, 문서화까지 함께 이어지는
|
|
10
|
+
Bun-first 풀스택 TypeScript 프레임워크입니다.
|
|
11
11
|
|
|
12
12
|
```bash
|
|
13
13
|
bunx create-akan-workspace@latest
|
|
@@ -15,14 +15,14 @@ bunx create-akan-workspace@latest
|
|
|
15
15
|
|
|
16
16
|
## 왜 Akan인가
|
|
17
17
|
|
|
18
|
-
Akan은 기술
|
|
19
|
-
|
|
20
|
-
|
|
18
|
+
Akan은 기술 계층을 손으로 배선하는 대신 비즈니스를 먼저 출시하도록 돕습니다. 도메인을 한 번
|
|
19
|
+
정의하면 schema, API, fetch client, store, UI, server, app packaging, deployment artifact,
|
|
20
|
+
generated reference가 같은 의도에서 이어집니다.
|
|
21
21
|
|
|
22
|
-
-
|
|
23
|
-
-
|
|
24
|
-
- **
|
|
25
|
-
- **
|
|
22
|
+
- **웹 개발자**: 같은 비즈니스 코드가 SEO 웹과 네이티브 느낌의 iOS/Android 화면까지 이어집니다.
|
|
23
|
+
- **앱 개발자**: Bun 서버, SQLite, API 계약, 검증이 손배선 없이 따라옵니다.
|
|
24
|
+
- **1인 창업가 / 소규모 팀**: 풀스택 1명이 5개 표면을 책임집니다. 사람 한 명, 코드 1/4.
|
|
25
|
+
- **AI 에이전트도 일관되게**: 엄격한 규칙이 파일 위치, 이름, 구조, 선언 방식을 읽기 좋게 유지합니다.
|
|
26
26
|
|
|
27
27
|
## 요구사항
|
|
28
28
|
|
|
@@ -104,12 +104,39 @@ flowchart LR
|
|
|
104
104
|
하나의 모델과 하나의 계약이 DB, 서버, API, 상태관리, UI까지 이어지기 때문에 계층마다 의도를
|
|
105
105
|
반복해서 작성할 필요가 줄어듭니다.
|
|
106
106
|
|
|
107
|
+
## 8 in 1
|
|
108
|
+
|
|
109
|
+
필드 하나. 8개 레이어가 따라옵니다.
|
|
110
|
+
|
|
111
|
+
기존 풀스택 앱에서 비즈니스 필드 하나를 추가하려면 보통 이만큼을 직접 손으로 해야 합니다.
|
|
112
|
+
|
|
113
|
+
1. DB 스키마 정의.
|
|
114
|
+
2. 쿼리 필드 추가.
|
|
115
|
+
3. 서비스 로직 추가.
|
|
116
|
+
4. API 필드 추가.
|
|
117
|
+
5. fetch 필드 추가.
|
|
118
|
+
6. 클라이언트 타입 선언.
|
|
119
|
+
7. 상태관리 선언.
|
|
120
|
+
8. UI prop 선언.
|
|
121
|
+
|
|
122
|
+
한 곳만 바뀌어도 8곳을 따라 고쳐야 하고, 한 곳을 빠뜨리면 타입이 깨지거나 런타임에서 터집니다.
|
|
123
|
+
Akan에서는 비즈니스 필드가 코드의 원천입니다.
|
|
124
|
+
|
|
125
|
+
```ts
|
|
126
|
+
export class ProductInput extends via((field) => ({
|
|
127
|
+
name: field(String),
|
|
128
|
+
})) {}
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
이 선언 하나로 스키마와 타입이 동시에 정의됩니다. 주변 레이어는 같은 의도에서 생성되므로 스택이
|
|
132
|
+
흩어져 스파게티가 되는 일을 줄입니다.
|
|
133
|
+
|
|
107
134
|
## Akan이 만드는 것
|
|
108
135
|
|
|
109
136
|
Akan은 보통 여러 프로젝트로 흩어지는 것들을 하나의 프레임워크로 묶습니다.
|
|
110
137
|
|
|
111
138
|
- SEO에 최적화된 server-side rendered web surface.
|
|
112
|
-
-
|
|
139
|
+
- 컴파일된 웹 surface를 앱으로 패키징한 iOS/Android surface와 네이티브 수준의 built-in 화면 전환.
|
|
113
140
|
- Bun 기반 HTTP/WebSocket server.
|
|
114
141
|
- SQLite-first 단순 서버 경로와 더 큰 시스템을 위한 Postgres/Redis 확장 경로.
|
|
115
142
|
- Schema validation, error handling, security helper, middleware.
|
|
@@ -121,6 +148,10 @@ Akan은 보통 여러 프로젝트로 흩어지는 것들을 하나의 프레임
|
|
|
121
148
|
배포와 문서 작성에 하루를 쓰고 있다면 뭔가 잘못된 것입니다. Akan은 schema와 endpoint 정의가
|
|
122
149
|
table reference, runtime contract, API docs, testable endpoint reference가 되도록 설계됩니다.
|
|
123
150
|
|
|
151
|
+
일반적인 앱 패키징은 감싼 웹사이트처럼 느껴지기 쉽습니다. Akan의 client runtime은 목록-상세 흐름,
|
|
152
|
+
오버레이, 맥락 전환을 위한 transition preset을 제공하므로 별도 UI 재작성 없이도 앱 패키징된 웹에서
|
|
153
|
+
네이티브 수준의 사용자 경험을 만들 수 있습니다.
|
|
154
|
+
|
|
124
155
|
## 하나의 패키지, 여러 경계
|
|
125
156
|
|
|
126
157
|
Akan은 하나의 npm package인 `akanjs`로 배포됩니다.
|
package/README.md
CHANGED
|
@@ -2,11 +2,11 @@
|
|
|
2
2
|
|
|
3
3
|
[한국어](https://unpkg.com/akanjs@latest/README.ko.md) | [Docs](https://akanjs.com/docs) | [npm](https://www.npmjs.com/package/akanjs)
|
|
4
4
|
|
|
5
|
-
**
|
|
5
|
+
**One line of business code ships web, iOS, Android, server, and database together.**
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
database contracts, infrastructure artifacts, and documentation.
|
|
7
|
+
No more framework assembly, duplicated declarations, or per-platform rewrites. Akan.js is a Bun-first
|
|
8
|
+
full-stack TypeScript framework where business intent is written once, then compiled into SEO web surfaces,
|
|
9
|
+
iOS and Android app packages, servers, database contracts, infrastructure artifacts, and documentation.
|
|
10
10
|
|
|
11
11
|
```bash
|
|
12
12
|
bunx create-akan-workspace@latest
|
|
@@ -14,14 +14,14 @@ bunx create-akan-workspace@latest
|
|
|
14
14
|
|
|
15
15
|
## Why Akan
|
|
16
16
|
|
|
17
|
-
Akan is designed for teams and solo builders who would rather
|
|
18
|
-
|
|
19
|
-
|
|
17
|
+
Akan is designed for teams and solo builders who would rather ship the business than keep wiring technical
|
|
18
|
+
layers by hand. Define the domain once, then let the framework connect schema, API, fetch client, store, UI,
|
|
19
|
+
server, app packaging, deployment artifacts, and generated references.
|
|
20
20
|
|
|
21
|
-
- **
|
|
22
|
-
- **
|
|
23
|
-
- **
|
|
24
|
-
- **
|
|
21
|
+
- **Web devs**: the same business code becomes SEO-ready web and native-feeling iOS/Android screens.
|
|
22
|
+
- **App devs**: Bun server, SQLite, API contracts, and validation follow without hand-wiring.
|
|
23
|
+
- **Solo and small teams**: one full-stack developer can own all five surfaces with a quarter of the code.
|
|
24
|
+
- **Agents stay consistent**: strict conventions keep file paths, names, structures, and declarations readable.
|
|
25
25
|
|
|
26
26
|
## Requirements
|
|
27
27
|
|
|
@@ -102,12 +102,39 @@ flowchart LR
|
|
|
102
102
|
This structure lets one model and one contract flow through the database, server, API, state management,
|
|
103
103
|
and UI without duplicating intent across layers.
|
|
104
104
|
|
|
105
|
+
## 8 in 1
|
|
106
|
+
|
|
107
|
+
One field. Eight layers follow.
|
|
108
|
+
|
|
109
|
+
Adding a single business field in a traditional full-stack app usually means changing all of this by hand:
|
|
110
|
+
|
|
111
|
+
1. Define the DB schema.
|
|
112
|
+
2. Add the query field.
|
|
113
|
+
3. Add the service logic.
|
|
114
|
+
4. Add the API field.
|
|
115
|
+
5. Add the fetch field.
|
|
116
|
+
6. Declare the client type.
|
|
117
|
+
7. Declare the state management.
|
|
118
|
+
8. Declare the UI prop.
|
|
119
|
+
|
|
120
|
+
Change one place, chase eight. Miss one, and types break, or it fails at runtime. In Akan, the business field is
|
|
121
|
+
the source of truth:
|
|
122
|
+
|
|
123
|
+
```ts
|
|
124
|
+
export class ProductInput extends via((field) => ({
|
|
125
|
+
name: field(String),
|
|
126
|
+
})) {}
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
That one declaration defines schema and type together. The surrounding layers are generated from the same
|
|
130
|
+
intent, so the stack stays connected instead of turning into spaghetti.
|
|
131
|
+
|
|
105
132
|
## What Akan Builds
|
|
106
133
|
|
|
107
134
|
Akan is one framework for the pieces that normally become separate projects:
|
|
108
135
|
|
|
109
136
|
- SEO-optimized server-side rendered web surfaces.
|
|
110
|
-
- iOS and Android
|
|
137
|
+
- iOS and Android app packages from compiled web surfaces, with native-level built-in screen transitions.
|
|
111
138
|
- Bun-powered HTTP and WebSocket servers.
|
|
112
139
|
- SQLite-first simple server paths, with Postgres and Redis expansion paths for larger systems.
|
|
113
140
|
- Schema validation, error handling, security helpers, and middleware.
|
|
@@ -119,6 +146,10 @@ Akan is one framework for the pieces that normally become separate projects:
|
|
|
119
146
|
Deployment and documentation should not consume a day of work. Akan is built so schema and endpoint
|
|
120
147
|
definitions can also become table references, runtime contracts, API docs, and testable endpoint references.
|
|
121
148
|
|
|
149
|
+
Unlike ordinary app packaging that can feel like a wrapped website, Akan's client runtime includes transition
|
|
150
|
+
presets for list-detail flows, overlays, and context changes. Packaged web surfaces can deliver a native-level
|
|
151
|
+
user experience without a separate UI rewrite.
|
|
152
|
+
|
|
122
153
|
## One Package, Many Boundaries
|
|
123
154
|
|
|
124
155
|
Akan is published as a single npm package: `akanjs`.
|
|
@@ -273,15 +273,26 @@ export class ConstantRegistry {
|
|
|
273
273
|
}
|
|
274
274
|
}
|
|
275
275
|
|
|
276
|
-
export interface
|
|
276
|
+
export interface ConstantModel<
|
|
277
277
|
T extends string = string,
|
|
278
|
-
Input =
|
|
279
|
-
Obj =
|
|
280
|
-
Full =
|
|
281
|
-
Light =
|
|
282
|
-
Insight =
|
|
278
|
+
Input = any,
|
|
279
|
+
Obj = any,
|
|
280
|
+
Full = any,
|
|
281
|
+
Light = any,
|
|
282
|
+
Insight = any,
|
|
283
283
|
FullFieldObj extends FieldObject = FieldObject,
|
|
284
284
|
_CapitalizedRefName extends string = Capitalize<T>,
|
|
285
|
+
_Default = DefaultOf<Full>,
|
|
286
|
+
_DefaultInput = DefaultOf<Input>,
|
|
287
|
+
_DefaultState = GetStateObject<Full>,
|
|
288
|
+
_DefaultStateInput = GetStateObject<Input>,
|
|
289
|
+
_DefaultInsight = DefaultOf<Insight>,
|
|
290
|
+
_PurifiedInput = PurifiedModel<Input>,
|
|
291
|
+
_Doc = DocumentModel<Full>,
|
|
292
|
+
_DocInput = DocumentModel<Input>,
|
|
293
|
+
_QueryOfDoc = QueryOf<_Doc>,
|
|
294
|
+
_StateLight = GetStateObject<Light>,
|
|
295
|
+
_StateInsight = GetStateObject<Insight>,
|
|
285
296
|
> {
|
|
286
297
|
refName: T;
|
|
287
298
|
input: ConstantCls<Input>;
|
|
@@ -295,25 +306,6 @@ export interface ConstantCore<
|
|
|
295
306
|
_Full: Full;
|
|
296
307
|
_Light: Light;
|
|
297
308
|
_Insight: Insight;
|
|
298
|
-
}
|
|
299
|
-
|
|
300
|
-
export interface ConstantDerived<
|
|
301
|
-
Input = unknown,
|
|
302
|
-
Full = unknown,
|
|
303
|
-
Light = unknown,
|
|
304
|
-
Insight = unknown,
|
|
305
|
-
_Default = DefaultOf<Full>,
|
|
306
|
-
_DefaultInput = DefaultOf<Input>,
|
|
307
|
-
_DefaultState = GetStateObject<Full>,
|
|
308
|
-
_DefaultStateInput = GetStateObject<Input>,
|
|
309
|
-
_DefaultInsight = DefaultOf<Insight>,
|
|
310
|
-
_PurifiedInput = PurifiedModel<Input>,
|
|
311
|
-
_Doc = DocumentModel<Full>,
|
|
312
|
-
_DocInput = DocumentModel<Input>,
|
|
313
|
-
_QueryOfDoc = QueryOf<_Doc>,
|
|
314
|
-
_StateLight = GetStateObject<Light>,
|
|
315
|
-
_StateInsight = GetStateObject<Insight>,
|
|
316
|
-
> {
|
|
317
309
|
_Default: _Default;
|
|
318
310
|
_DefaultInput: _DefaultInput;
|
|
319
311
|
_DefaultState: _DefaultState;
|
|
@@ -327,98 +319,6 @@ export interface ConstantDerived<
|
|
|
327
319
|
_StateInsight: _StateInsight;
|
|
328
320
|
}
|
|
329
321
|
|
|
330
|
-
export interface ConstantModel<
|
|
331
|
-
T extends string = string,
|
|
332
|
-
Input = any,
|
|
333
|
-
Obj = any,
|
|
334
|
-
Full = any,
|
|
335
|
-
Light = any,
|
|
336
|
-
Insight = any,
|
|
337
|
-
FullFieldObj extends FieldObject = FieldObject,
|
|
338
|
-
_CapitalizedRefName extends string = Capitalize<T>,
|
|
339
|
-
_Default = DefaultOf<Full>,
|
|
340
|
-
_DefaultInput = DefaultOf<Input>,
|
|
341
|
-
_DefaultState = GetStateObject<Full>,
|
|
342
|
-
_DefaultStateInput = GetStateObject<Input>,
|
|
343
|
-
_DefaultInsight = DefaultOf<Insight>,
|
|
344
|
-
_PurifiedInput = PurifiedModel<Input>,
|
|
345
|
-
_Doc = DocumentModel<Full>,
|
|
346
|
-
_DocInput = DocumentModel<Input>,
|
|
347
|
-
_QueryOfDoc = QueryOf<_Doc>,
|
|
348
|
-
_StateLight = GetStateObject<Light>,
|
|
349
|
-
_StateInsight = GetStateObject<Insight>,
|
|
350
|
-
> extends ConstantCore<T, Input, Obj, Full, Light, Insight, FullFieldObj, _CapitalizedRefName>,
|
|
351
|
-
ConstantDerived<
|
|
352
|
-
Input,
|
|
353
|
-
Full,
|
|
354
|
-
Light,
|
|
355
|
-
Insight,
|
|
356
|
-
_Default,
|
|
357
|
-
_DefaultInput,
|
|
358
|
-
_DefaultState,
|
|
359
|
-
_DefaultStateInput,
|
|
360
|
-
_DefaultInsight,
|
|
361
|
-
_PurifiedInput,
|
|
362
|
-
_Doc,
|
|
363
|
-
_DocInput,
|
|
364
|
-
_QueryOfDoc,
|
|
365
|
-
_StateLight,
|
|
366
|
-
_StateInsight
|
|
367
|
-
> {}
|
|
368
|
-
|
|
369
|
-
export type ConstantReturnView<Full = unknown, Light = unknown, Insight = unknown> = {
|
|
370
|
-
full: Full;
|
|
371
|
-
light: Light;
|
|
372
|
-
insight: Insight;
|
|
373
|
-
};
|
|
374
|
-
|
|
375
|
-
export type ConstantReturnViewOf<Cnst> = Cnst extends {
|
|
376
|
-
_Full: infer Full;
|
|
377
|
-
_Light: infer Light;
|
|
378
|
-
_Insight: infer Insight;
|
|
379
|
-
}
|
|
380
|
-
? ConstantReturnView<Full, Light, Insight>
|
|
381
|
-
: never;
|
|
382
|
-
|
|
383
|
-
export type ConstantFetchView<
|
|
384
|
-
RefName extends string = string,
|
|
385
|
-
CapRefName extends string = Capitalize<RefName>,
|
|
386
|
-
Input = unknown,
|
|
387
|
-
Full = unknown,
|
|
388
|
-
Light = unknown,
|
|
389
|
-
Insight = unknown,
|
|
390
|
-
PurifiedInput = unknown,
|
|
391
|
-
DefaultInput = unknown,
|
|
392
|
-
StateLight = unknown,
|
|
393
|
-
StateInsight = unknown,
|
|
394
|
-
> = {
|
|
395
|
-
refName: RefName;
|
|
396
|
-
capRefName: CapRefName;
|
|
397
|
-
input: Input;
|
|
398
|
-
full: Full;
|
|
399
|
-
light: Light;
|
|
400
|
-
insight: Insight;
|
|
401
|
-
purifiedInput: PurifiedInput;
|
|
402
|
-
defaultInput: DefaultInput;
|
|
403
|
-
stateLight: StateLight;
|
|
404
|
-
stateInsight: StateInsight;
|
|
405
|
-
};
|
|
406
|
-
|
|
407
|
-
export type ConstantFetchViewOf<Cnst> = Cnst extends {
|
|
408
|
-
refName: infer RefName extends string;
|
|
409
|
-
_CapitalizedRefName: infer CapRefName extends string;
|
|
410
|
-
_Input: infer Input;
|
|
411
|
-
_Full: infer Full;
|
|
412
|
-
_Light: infer Light;
|
|
413
|
-
_Insight: infer Insight;
|
|
414
|
-
_PurifiedInput: infer PurifiedInput;
|
|
415
|
-
_DefaultInput: infer DefaultInput;
|
|
416
|
-
_StateLight: infer StateLight;
|
|
417
|
-
_StateInsight: infer StateInsight;
|
|
418
|
-
}
|
|
419
|
-
? ConstantFetchView<RefName, CapRefName, Input, Full, Light, Insight, PurifiedInput, DefaultInput, StateLight, StateInsight>
|
|
420
|
-
: never;
|
|
421
|
-
|
|
422
322
|
export interface ScalarConstantModel<
|
|
423
323
|
T extends string = string,
|
|
424
324
|
Model = any,
|
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
import type { DatabaseSignal, SerializedSignal, ServiceSignal } from "akanjs/signal";
|
|
1
|
+
import type { DatabaseSignal, EndpointCls, SerializedSignal, ServiceSignal, SliceCls } from "akanjs/signal";
|
|
3
2
|
import type { FetchProxy } from "../client";
|
|
4
3
|
import type { GetSliceMetaObjFromDatabaseSignals } from "../types";
|
|
5
4
|
import type { SliceMeta } from "./appliedReturn.type";
|
|
@@ -18,28 +17,36 @@ export type FetchProxySignalInput<
|
|
|
18
17
|
|
|
19
18
|
export type FetchSignalInput = FetchProxySignalInput | DatabaseSignal | ServiceSignal;
|
|
20
19
|
|
|
21
|
-
type MergeFetchParts<First, Second> = [First] extends [never]
|
|
22
|
-
? Second
|
|
23
|
-
: [Second] extends [never]
|
|
24
|
-
? First
|
|
25
|
-
: Assign<First, Second>;
|
|
26
|
-
|
|
27
20
|
export type FetchTypeOfSignal<Signal extends FetchSignalInput> = Signal extends { _FetchType: infer FetchType }
|
|
28
21
|
? FetchType
|
|
29
|
-
: Signal extends
|
|
30
|
-
?
|
|
31
|
-
: Signal extends
|
|
22
|
+
: Signal extends { endpoint: infer EndpCls extends EndpointCls; slice: infer SlceCls extends SliceCls }
|
|
23
|
+
? GetFetchTypeFromEndpoint<EndpCls, SlceCls> & GetFetchTypeFromSlice<SlceCls>
|
|
24
|
+
: Signal extends { endpoint: infer EndpCls extends EndpointCls }
|
|
32
25
|
? GetFetchTypeFromEndpoint<EndpCls>
|
|
33
26
|
: unknown;
|
|
34
27
|
|
|
35
|
-
type
|
|
28
|
+
type FetchKeysOfProxySignal<Signal> = Signal extends { _FetchType: infer FetchType } ? keyof FetchType : never;
|
|
29
|
+
type FetchKeysOfProxySignals<Signals extends readonly FetchSignalInput[]> = FetchKeysOfProxySignal<Signals[number]>;
|
|
30
|
+
|
|
31
|
+
type LastProxyFetchValue<
|
|
36
32
|
Signals extends readonly FetchSignalInput[],
|
|
37
|
-
|
|
33
|
+
Key extends PropertyKey,
|
|
34
|
+
Current = never,
|
|
38
35
|
> = Signals extends readonly [infer First extends FetchSignalInput, ...infer Rest extends readonly FetchSignalInput[]]
|
|
39
36
|
? First extends { _FetchType: infer FetchType }
|
|
40
|
-
?
|
|
41
|
-
|
|
42
|
-
|
|
37
|
+
? Key extends keyof FetchType
|
|
38
|
+
? LastProxyFetchValue<Rest, Key, FetchType[Key]>
|
|
39
|
+
: LastProxyFetchValue<Rest, Key, Current>
|
|
40
|
+
: LastProxyFetchValue<Rest, Key, Current>
|
|
41
|
+
: Current;
|
|
42
|
+
|
|
43
|
+
type MergeProxyFetchTypes<Signals extends readonly FetchSignalInput[]> = [FetchKeysOfProxySignals<Signals>] extends [
|
|
44
|
+
never,
|
|
45
|
+
]
|
|
46
|
+
? Record<never, never>
|
|
47
|
+
: {
|
|
48
|
+
[Key in FetchKeysOfProxySignals<Signals>]: LastProxyFetchValue<Signals, Key>;
|
|
49
|
+
};
|
|
43
50
|
|
|
44
51
|
type MergeDirectFetchTypes<
|
|
45
52
|
Signals extends readonly FetchSignalInput[],
|
|
@@ -47,13 +54,13 @@ type MergeDirectFetchTypes<
|
|
|
47
54
|
> = Signals extends readonly [infer First extends FetchSignalInput, ...infer Rest extends readonly FetchSignalInput[]]
|
|
48
55
|
? First extends { _FetchType: unknown }
|
|
49
56
|
? MergeDirectFetchTypes<Rest, Acc>
|
|
50
|
-
: MergeDirectFetchTypes<Rest,
|
|
57
|
+
: MergeDirectFetchTypes<Rest, Acc & FetchTypeOfSignal<First>>
|
|
51
58
|
: Acc;
|
|
52
59
|
|
|
53
60
|
export type MergeAllFetchTypes<Signals extends readonly FetchSignalInput[]> =
|
|
54
61
|
MergeProxyFetchTypes<Signals> extends infer ProxyFetch
|
|
55
62
|
? MergeDirectFetchTypes<Signals> extends infer DirectFetch
|
|
56
|
-
?
|
|
63
|
+
? Omit<ProxyFetch, keyof DirectFetch> & DirectFetch
|
|
57
64
|
: never
|
|
58
65
|
: never;
|
|
59
66
|
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import type { ENDPOINT_META, PromiseOrObject } from "akanjs/base";
|
|
2
2
|
import type { FetchPolicy } from "akanjs/common";
|
|
3
|
-
import type { ConstantReturnViewOf } from "akanjs/constant";
|
|
4
3
|
import type {
|
|
5
4
|
EndpInfoArgs,
|
|
6
5
|
EndpInfoClientReturns,
|
|
@@ -11,112 +10,81 @@ import type {
|
|
|
11
10
|
SliceCls,
|
|
12
11
|
} from "akanjs/signal";
|
|
13
12
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
type ExtendedEndpointReturn<ClientReturns, Context> = ClientReturns extends (infer R)[]
|
|
27
|
-
? ExtendedEndpointReturn<R, Context>[]
|
|
28
|
-
: Context extends EndpointReturnContext<infer Full, infer Light, infer Insight>
|
|
29
|
-
? Full extends ClientReturns
|
|
30
|
-
? Full
|
|
31
|
-
: Light extends ClientReturns
|
|
32
|
-
? Light
|
|
33
|
-
: Insight extends ClientReturns
|
|
34
|
-
? Insight
|
|
35
|
-
: ClientReturns
|
|
36
|
-
: ClientReturns;
|
|
37
|
-
|
|
38
|
-
type EndpointClientReturns<E, Context> = [Context] extends [never]
|
|
13
|
+
type ExtendedEndpointReturn<ClientReturns, Full, Light, Insight> = ClientReturns extends (infer R)[]
|
|
14
|
+
? ExtendedEndpointReturn<R, Full, Light, Insight>[]
|
|
15
|
+
: Full extends ClientReturns
|
|
16
|
+
? Full
|
|
17
|
+
: Light extends ClientReturns
|
|
18
|
+
? Light
|
|
19
|
+
: Insight extends ClientReturns
|
|
20
|
+
? Insight
|
|
21
|
+
: ClientReturns;
|
|
22
|
+
|
|
23
|
+
type EndpointClientReturns<E, SlceCls extends SliceCls | never> = [SlceCls] extends [never]
|
|
39
24
|
? EndpInfoClientReturns<E>
|
|
40
|
-
: ExtendedEndpointReturn<
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
25
|
+
: ExtendedEndpointReturn<
|
|
26
|
+
EndpInfoClientReturns<E>,
|
|
27
|
+
SlceCls["srv"]["cnst"]["_Full"],
|
|
28
|
+
SlceCls["srv"]["cnst"]["_Light"],
|
|
29
|
+
SlceCls["srv"]["cnst"]["_Insight"]
|
|
30
|
+
>;
|
|
31
|
+
|
|
32
|
+
type EndpInfoReturns<E, SlceCls extends SliceCls | never> =
|
|
33
|
+
| EndpointClientReturns<E, SlceCls>
|
|
44
34
|
| (EndpInfoNullable<E> extends true ? null : never);
|
|
45
35
|
|
|
46
|
-
type QueryOrMutationFetchFn<E,
|
|
36
|
+
type QueryOrMutationFetchFn<E, SlceCls extends SliceCls | never> = (
|
|
47
37
|
...args: [...EndpInfoArgs<E>, fetchPolicy?: FetchPolicy]
|
|
48
|
-
) => Promise<EndpInfoReturns<E,
|
|
38
|
+
) => Promise<EndpInfoReturns<E, SlceCls>>;
|
|
49
39
|
|
|
50
|
-
type MessageEmitFn<E,
|
|
40
|
+
type MessageEmitFn<E, SlceCls extends SliceCls | never> = (...args: EndpInfoArgs<E>) => EndpInfoReturns<E, SlceCls>;
|
|
51
41
|
|
|
52
|
-
type MessageListenFn<E,
|
|
53
|
-
handleEvent: (data: EndpInfoReturns<E,
|
|
42
|
+
type MessageListenFn<E, SlceCls extends SliceCls | never> = (
|
|
43
|
+
handleEvent: (data: EndpInfoReturns<E, SlceCls>) => PromiseOrObject<void>,
|
|
54
44
|
options?: FetchPolicy,
|
|
55
45
|
) => () => void;
|
|
56
46
|
|
|
57
|
-
type PubsubSubscribeFn<E,
|
|
47
|
+
type PubsubSubscribeFn<E, SlceCls extends SliceCls | never> = (
|
|
58
48
|
...args: [
|
|
59
49
|
...EndpInfoArgs<E>,
|
|
60
|
-
handleEvent: (data: EndpInfoReturns<E,
|
|
50
|
+
handleEvent: (data: EndpInfoReturns<E, SlceCls>) => PromiseOrObject<void>,
|
|
61
51
|
options?: FetchPolicy,
|
|
62
52
|
]
|
|
63
53
|
) => () => void;
|
|
64
54
|
|
|
65
|
-
type PrimaryFetchFn<E,
|
|
66
|
-
|
|
67
|
-
? QueryOrMutationFetchFn<E,
|
|
68
|
-
:
|
|
69
|
-
? MessageEmitFn<E,
|
|
55
|
+
type PrimaryFetchFn<E, SlceCls extends SliceCls | never> =
|
|
56
|
+
EndpInfoReqType<E> extends "query" | "mutation"
|
|
57
|
+
? QueryOrMutationFetchFn<E, SlceCls>
|
|
58
|
+
: EndpInfoReqType<E> extends "message"
|
|
59
|
+
? MessageEmitFn<E, SlceCls>
|
|
70
60
|
: never;
|
|
71
61
|
|
|
72
|
-
type
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
[K in keyof Args]: RestApiArg<Args[K]>;
|
|
77
|
-
};
|
|
78
|
-
type UploadRestApiFetchFn<E, Context> = (
|
|
79
|
-
...args: [...RestApiArgs<EndpInfoArgs<E>>, fetchPolicy?: FetchPolicy]
|
|
80
|
-
) => Promise<EndpInfoReturns<E, Context>>;
|
|
81
|
-
|
|
82
|
-
type PrimaryFetchType<EInfoObj extends { [key: string]: EndpointInfo }, Context> = {
|
|
83
|
-
[K in keyof EInfoObj as Extract<EndpInfoReqType<EInfoObj[K]>, "query" | "mutation" | "message"> extends never
|
|
84
|
-
? never
|
|
85
|
-
: K]: PrimaryFetchFn<EInfoObj[K], Context>;
|
|
86
|
-
};
|
|
87
|
-
|
|
88
|
-
type UploadRestApiFetchType<EInfoObj extends { [key: string]: EndpointInfo }, Context> = {
|
|
89
|
-
[K in keyof EInfoObj as Extract<EndpInfoReqType<EInfoObj[K]>, "mutation"> extends never
|
|
90
|
-
? never
|
|
91
|
-
: HasUploadLikeArg<EndpInfoArgs<EInfoObj[K]>> extends true
|
|
92
|
-
? K extends string
|
|
93
|
-
? `${K}RestApi`
|
|
94
|
-
: never
|
|
95
|
-
: never]: UploadRestApiFetchFn<EInfoObj[K], Context>;
|
|
62
|
+
type PrimaryFetchType<EInfoObj extends { [key: string]: EndpointInfo }, SlceCls extends SliceCls | never> = {
|
|
63
|
+
[K in keyof EInfoObj as EndpInfoReqType<EInfoObj[K]> extends "query" | "mutation" | "message"
|
|
64
|
+
? K
|
|
65
|
+
: never]: PrimaryFetchFn<EInfoObj[K], SlceCls>;
|
|
96
66
|
};
|
|
97
67
|
|
|
98
|
-
type PubsubFetchType<EInfoObj extends { [key: string]: EndpointInfo },
|
|
99
|
-
[K in keyof EInfoObj as
|
|
100
|
-
?
|
|
101
|
-
: K extends string
|
|
68
|
+
type PubsubFetchType<EInfoObj extends { [key: string]: EndpointInfo }, SlceCls extends SliceCls | never> = {
|
|
69
|
+
[K in keyof EInfoObj as EndpInfoReqType<EInfoObj[K]> extends "pubsub"
|
|
70
|
+
? K extends string
|
|
102
71
|
? `subscribe${Capitalize<K>}`
|
|
103
|
-
: never
|
|
72
|
+
: never
|
|
73
|
+
: never]: PubsubSubscribeFn<EInfoObj[K], SlceCls>;
|
|
104
74
|
};
|
|
105
75
|
|
|
106
|
-
type MessageListenFetchType<EInfoObj extends { [key: string]: EndpointInfo },
|
|
107
|
-
[K in keyof EInfoObj as
|
|
108
|
-
?
|
|
109
|
-
: K extends string
|
|
76
|
+
type MessageListenFetchType<EInfoObj extends { [key: string]: EndpointInfo }, SlceCls extends SliceCls | never> = {
|
|
77
|
+
[K in keyof EInfoObj as EndpInfoReqType<EInfoObj[K]> extends "message"
|
|
78
|
+
? K extends string
|
|
110
79
|
? `listen${Capitalize<K>}`
|
|
111
|
-
: never
|
|
80
|
+
: never
|
|
81
|
+
: never]: MessageListenFn<EInfoObj[K], SlceCls>;
|
|
112
82
|
};
|
|
113
83
|
|
|
114
84
|
export type GetFetchTypeFromEndpoint<
|
|
115
85
|
EndpCls extends EndpointCls,
|
|
116
86
|
SlceCls extends SliceCls | never = never,
|
|
117
87
|
_EndpointInfoObj extends { [key: string]: EndpointInfo } = EndpCls[typeof ENDPOINT_META],
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
PubsubFetchType<_EndpointInfoObj, _ReturnContext> &
|
|
122
|
-
MessageListenFetchType<_EndpointInfoObj, _ReturnContext>;
|
|
88
|
+
> = PrimaryFetchType<_EndpointInfoObj, SlceCls> &
|
|
89
|
+
PubsubFetchType<_EndpointInfoObj, SlceCls> &
|
|
90
|
+
MessageListenFetchType<_EndpointInfoObj, SlceCls>;
|