@spaceteams/warp 0.3.0 → 0.3.1

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/index.d.mts CHANGED
@@ -1,6 +1,20 @@
1
+ //#region src/component/component-meta.d.ts
2
+ type ComponentKind = "repo" | "service" | "usecase" | "client";
3
+ type ComponentMeta = {
4
+ name?: string;
5
+ kind?: ComponentKind;
6
+ tags?: string[];
7
+ };
8
+ //#endregion
1
9
  //#region src/run.d.ts
10
+ type WarpMeta = {
11
+ component?: ComponentMeta;
12
+ componentPath?: string;
13
+ componentKey?: string;
14
+ };
2
15
  type Run<AmbientContext, ScopeContext = unknown, RunOptions = unknown> = AmbientContext & {
3
16
  run: <T>(options: RunOptions, inner: (app: Run<AmbientContext & ScopeContext, ScopeContext, RunOptions>) => Promise<T> | T) => Promise<T> | T;
17
+ warp?: WarpMeta;
4
18
  };
5
19
  //#endregion
6
20
  //#region src/component/index.d.ts
@@ -13,12 +27,6 @@ type ComponentRef<Ctx, ScopeContext, RunOptions, Out> = {
13
27
  readonly __runOptions?: RunOptions;
14
28
  readonly __out?: Out;
15
29
  };
16
- type ComponentKind = "repo" | "service" | "usecase" | "client";
17
- type ComponentMeta = {
18
- name?: string;
19
- kind?: ComponentKind;
20
- tags?: string[];
21
- };
22
30
  type ComponentFactoryFn<Ctx, ScopeContext, RunOptions, Deps, Out> = (ctx: Run<Ctx & Deps, ScopeContext, RunOptions>) => Out;
23
31
  type ComponentFactory<Ctx, ScopeContext, RunOptions, Deps, Out> = ComponentFactoryFn<Ctx, ScopeContext, RunOptions, Deps, Out> & {
24
32
  meta?: ComponentMeta;
@@ -40,7 +48,7 @@ declare function isComponent(value: unknown): value is Component<unknown, unknow
40
48
  //#region src/middleware.d.ts
41
49
  type NoRunOptions = NonNullable<unknown>;
42
50
  type NoScopeContext = NonNullable<unknown>;
43
- type Middleware<AmbientContext, RunOptions = NoRunOptions, ScopeContext = NoScopeContext> = <T>(ctx: AmbientContext, options: Partial<RunOptions>, next: (ctx: AmbientContext & ScopeContext) => Promise<T> | T) => Promise<T> | T;
51
+ type Middleware<AmbientContext, RunOptions = NoRunOptions, ScopeContext = NoScopeContext> = <T>(ctx: AmbientContext, options: Partial<RunOptions>, next: (ctx: AmbientContext & ScopeContext) => Promise<T> | T, warp?: WarpMeta | undefined) => Promise<T> | T;
44
52
  //#endregion
45
53
  //#region src/explain/index.d.ts
46
54
  type ExplainResult = {
@@ -51,11 +59,11 @@ type ExplainResult = {
51
59
  };
52
60
  //#endregion
53
61
  //#region src/lazy.d.ts
54
- type Lazy<T> = () => T;
62
+ type Lazy<T, Args extends unknown[] = []> = (...args: Args) => T;
55
63
  declare const Lazy: {
56
- cached<T>(factory: () => T): Lazy<T>;
57
- and<S, T>(l: Lazy<S>, r: Lazy<T>): Lazy<S & T>;
58
- map<S, T>(l: Lazy<S>, fn: (v: S) => T): Lazy<T>;
64
+ cached<T, Args extends unknown[] = []>(factory: Lazy<T, Args>): Lazy<T, Args>;
65
+ and<S, T, Args extends unknown[] = []>(l: Lazy<S, Args>, r: Lazy<T, Args>): Lazy<S & T, Args>;
66
+ map<S, T, Args extends unknown[] = []>(l: Lazy<S, Args>, fn: (v: S) => T): Lazy<T, Args>;
59
67
  };
60
68
  //#endregion
61
69
  //#region src/runtime/runtime.d.ts
@@ -71,9 +79,13 @@ declare class Runtime<Ctx, ActualContext extends Ctx, ScopeContext, RunOptions,
71
79
  require<Extension>(): Runtime<Ctx, ActualContext, ScopeContext, RunOptions, SafeIntersect<Requirements, Extension>>;
72
80
  resolve: <Deps, Out>(component: Component<SafeIntersect<Requirements, ActualContext>, ScopeContext, RunOptions, Deps, Out>, ...requirements: OptionalArg<Requirements>) => Out | Promise<Out>;
73
81
  get component(): <Deps, F extends ComponentFactory<SafeIntersect<Requirements, ActualContext>, ScopeContext, RunOptions, Deps, ReturnType<F>>>(factory: F, deps?: { [T in keyof Deps]: ComponentInput<SafeIntersect<Requirements, ActualContext>, ScopeContext, RunOptions, Deps[T]> } | undefined, meta?: ComponentMeta | undefined) => Component<SafeIntersect<Requirements, ActualContext>, ScopeContext, RunOptions, Deps, ReturnType<F>>;
82
+ get singleton(): <Deps, F extends ComponentFactory<SafeIntersect<Requirements, ActualContext>, {}, RunOptions, Deps, ReturnType<F>>>(factory: F, deps?: { [T in keyof Deps]: ComponentInput<SafeIntersect<Requirements, ActualContext>, {}, RunOptions, Deps[T]> } | undefined, meta?: ComponentMeta | undefined) => Component<SafeIntersect<Requirements, ActualContext>, {}, RunOptions, Deps, ReturnType<F>>;
74
83
  get classComponent(): <Deps, Ctor extends (new (deps: Run<SafeIntersect<Requirements, ActualContext> & Deps, ScopeContext, RunOptions>) => InstanceType<Ctor>) & {
75
84
  meta?: ComponentMeta | undefined;
76
85
  }>(ctor: Ctor, deps?: { [K in keyof Deps]: ComponentInput<SafeIntersect<Requirements, ActualContext>, ScopeContext, RunOptions, Deps[K]> } | undefined, meta?: ComponentMeta | undefined) => Component<SafeIntersect<Requirements, ActualContext>, ScopeContext, RunOptions, Deps, InstanceType<Ctor>>;
86
+ get classSingleton(): <Deps, Ctor extends (new (deps: Run<SafeIntersect<Requirements, ActualContext> & Deps, {}, RunOptions>) => InstanceType<Ctor>) & {
87
+ meta?: ComponentMeta | undefined;
88
+ }>(ctor: Ctor, deps?: { [K in keyof Deps]: ComponentInput<SafeIntersect<Requirements, ActualContext>, {}, RunOptions, Deps[K]> } | undefined, meta?: ComponentMeta | undefined) => Component<SafeIntersect<Requirements, ActualContext>, {}, RunOptions, Deps, InstanceType<Ctor>>;
77
89
  explain<Deps, Out>(component: Component<SafeIntersect<Requirements, ActualContext>, ScopeContext, RunOptions, Deps, Out>, format: "native", showMeta?: boolean): ExplainResult;
78
90
  explain<Deps, Out>(component: Component<SafeIntersect<Requirements, ActualContext>, ScopeContext, RunOptions, Deps, Out>, format: "ascii", showMeta?: boolean): string;
79
91
  explain<Deps, Out>(component: Component<SafeIntersect<Requirements, ActualContext>, ScopeContext, RunOptions, Deps, Out>, format: "mermaid", showMeta?: boolean): string;
@@ -118,4 +130,4 @@ type Usecase<Ctx, ScopeContext, Args extends unknown[], Result, RunOptions> = Ca
118
130
  declare function usecase<Ctx, Args extends unknown[], Result, RunOptions = NoRunOptions, ScopeContext = NoScopeContext>(options: RunOptions & Omit<ComponentMeta, "kind">, fn: (app: Run<Ctx, ScopeContext, RunOptions>) => (...args: Args) => Promise<Result>): Usecase<Ctx, ScopeContext, Args, Result, RunOptions>;
119
131
  type InferUsecase<T> = InferCallable<T>;
120
132
  //#endregion
121
- export { Callable, Client, Component, ComponentDefinition, ComponentFactory, ComponentFactoryFn, ComponentInput, ComponentKind, ComponentMeta, ComponentRef, InferCallable, InferClient, InferRepo, InferService, InferUsecase, Middleware, NoDeps, NoRunOptions, NoScopeContext, Repo, Run, Service, Usecase, brandComponent, buildRuntime, callable, client, isComponent, repo, service, usecase };
133
+ export { Callable, Client, Component, ComponentDefinition, ComponentFactory, ComponentFactoryFn, ComponentInput, ComponentKind, ComponentMeta, ComponentRef, InferCallable, InferClient, InferRepo, InferService, InferUsecase, Middleware, NoDeps, NoRunOptions, NoScopeContext, Repo, Run, Service, Usecase, WarpMeta, brandComponent, buildRuntime, callable, client, isComponent, repo, service, usecase };
package/dist/index.mjs CHANGED
@@ -17,19 +17,19 @@ function isComponent(value) {
17
17
  const Lazy = {
18
18
  cached(factory) {
19
19
  let cached;
20
- return () => {
21
- if (cached === void 0) cached = factory();
20
+ return (...args) => {
21
+ if (cached === void 0) cached = factory(...args);
22
22
  return cached;
23
23
  };
24
24
  },
25
25
  and(l, r) {
26
- return () => ({
27
- ...l(),
28
- ...r()
26
+ return (...args) => ({
27
+ ...l(...args),
28
+ ...r(...args)
29
29
  });
30
30
  },
31
31
  map(l, fn) {
32
- return () => fn(l());
32
+ return (...args) => fn(l(...args));
33
33
  }
34
34
  };
35
35
  //#endregion
@@ -51,6 +51,24 @@ function defineClassComponent() {
51
51
  };
52
52
  }
53
53
  //#endregion
54
+ //#region src/component/class-singleton.ts
55
+ function defineClassSingleton() {
56
+ return (ctor, deps, meta) => {
57
+ const factory = (ctx) => {
58
+ return new ctor(ctx);
59
+ };
60
+ return brandComponent({
61
+ factory: Lazy.cached(factory),
62
+ deps,
63
+ meta: {
64
+ name: (meta?.name ?? ctor.meta?.name) || void 0,
65
+ tags: (meta?.tags ?? ctor.meta?.tags) || void 0,
66
+ kind: (meta?.kind ?? ctor.meta?.kind) || void 0
67
+ }
68
+ });
69
+ };
70
+ }
71
+ //#endregion
54
72
  //#region src/component/functional-component.ts
55
73
  function defineFunctionalComponent() {
56
74
  return (factory, deps, meta) => {
@@ -66,6 +84,21 @@ function defineFunctionalComponent() {
66
84
  };
67
85
  }
68
86
  //#endregion
87
+ //#region src/component/functional-singleton.ts
88
+ function defineFunctionalSingleton() {
89
+ return (factory, deps, meta) => {
90
+ return brandComponent({
91
+ factory: Lazy.cached(factory),
92
+ deps,
93
+ meta: {
94
+ name: (meta?.name ?? factory.meta?.name) || void 0,
95
+ tags: (meta?.tags ?? factory.meta?.tags) || void 0,
96
+ kind: (meta?.kind ?? factory.meta?.kind) || void 0
97
+ }
98
+ });
99
+ };
100
+ }
101
+ //#endregion
69
102
  //#region src/explain/index.ts
70
103
  const explain = (c) => {
71
104
  const deps = {};
@@ -146,7 +179,7 @@ function createResolver(mw) {
146
179
  get() {
147
180
  if (cache.has(depName)) return cache.get(depName);
148
181
  checkCyclicDependency(depPath);
149
- const out = withStackTracking(depPath, () => bindInScope(depComp, scopeCtx, depPath));
182
+ const out = withStackTracking(depPath, () => bindInScope(depComp, scopeCtx, depPath, depName));
150
183
  cache.set(depName, out);
151
184
  return out;
152
185
  }
@@ -155,29 +188,34 @@ function createResolver(mw) {
155
188
  const attachDependencies = (runCtx, deps, scopeCtx, pathPrefix, cache) => {
156
189
  for (const [depName, depComp] of Object.entries(deps)) defineDependencyProperty(runCtx, depName, pathPrefix ? `${pathPrefix}.${depName}` : depName, depComp, scopeCtx, cache);
157
190
  };
158
- const createBaseRunContext = (scopeCtx) => {
191
+ const createBaseRunContext = (scopeCtx, warp) => {
159
192
  return {
160
193
  ...scopeCtx,
161
- run: (nestedOptions, nestedInner) => runWithContext(scopeCtx, nestedOptions, nestedInner)
194
+ warp,
195
+ run: (nestedOptions, nestedInner) => runWithContext(scopeCtx, nestedOptions, nestedInner, warp)
162
196
  };
163
197
  };
164
- const bindInScope = (comp, scopeCtx, path) => {
198
+ const bindInScope = (comp, scopeCtx, path, depName) => {
165
199
  const localDepCache = /* @__PURE__ */ new Map();
166
- const runCtx = createBaseRunContext(scopeCtx);
167
200
  if (!isComponent(comp)) return comp;
201
+ const runCtx = createBaseRunContext(scopeCtx, {
202
+ component: comp.meta,
203
+ componentPath: path,
204
+ componentKey: depName
205
+ });
168
206
  attachDependencies(runCtx, comp.deps ?? {}, scopeCtx, path, localDepCache);
169
207
  return comp.factory(runCtx);
170
208
  };
171
209
  const makeRootRunContext = (scopeCtx) => {
172
210
  const rootCache = /* @__PURE__ */ new Map();
173
- const runCtx = createBaseRunContext(scopeCtx);
211
+ const runCtx = createBaseRunContext(scopeCtx, { component: root.meta });
174
212
  attachDependencies(runCtx, root.deps ?? {}, scopeCtx, "", rootCache);
175
213
  return runCtx;
176
214
  };
177
- const runWithContext = async (currentCtx, options, inner) => {
215
+ const runWithContext = async (currentCtx, options, inner, warp) => {
178
216
  return await mw(currentCtx, options, (scopedCtx) => {
179
217
  return inner(makeRootRunContext(scopedCtx));
180
- });
218
+ }, warp);
181
219
  };
182
220
  return root.factory(makeRootRunContext(ctx));
183
221
  };
@@ -211,9 +249,15 @@ var Runtime = class Runtime {
211
249
  get component() {
212
250
  return defineFunctionalComponent();
213
251
  }
252
+ get singleton() {
253
+ return defineFunctionalSingleton();
254
+ }
214
255
  get classComponent() {
215
256
  return defineClassComponent();
216
257
  }
258
+ get classSingleton() {
259
+ return defineClassSingleton();
260
+ }
217
261
  explain(component, format = "native", showMeta = false) {
218
262
  const result = explain(component);
219
263
  switch (format) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@spaceteams/warp",
3
- "version": "0.3.0",
3
+ "version": "0.3.1",
4
4
  "description": "Type-safe composition with execution scopes ",
5
5
  "type": "module",
6
6
  "files": [