@diphyx/harlemify 2.0.0 → 4.0.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.
Files changed (55) hide show
  1. package/README.md +64 -119
  2. package/dist/module.d.mts +24 -13
  3. package/dist/module.d.ts +24 -13
  4. package/dist/module.json +1 -1
  5. package/dist/module.mjs +8 -10
  6. package/dist/runtime/composables/action.d.ts +4 -0
  7. package/dist/runtime/composables/action.js +8 -0
  8. package/dist/runtime/config.d.ts +10 -0
  9. package/dist/runtime/config.js +7 -0
  10. package/dist/runtime/core/layers/action.d.ts +4 -0
  11. package/dist/runtime/core/layers/action.js +102 -0
  12. package/dist/runtime/core/layers/model.d.ts +3 -0
  13. package/dist/runtime/core/layers/model.js +31 -0
  14. package/dist/runtime/core/layers/shape.d.ts +45 -0
  15. package/dist/runtime/core/layers/shape.js +56 -0
  16. package/dist/runtime/core/layers/view.d.ts +4 -0
  17. package/dist/runtime/core/layers/view.js +21 -0
  18. package/dist/runtime/core/store.d.ts +20 -72
  19. package/dist/runtime/core/store.js +49 -317
  20. package/dist/runtime/core/types/action.d.ts +162 -0
  21. package/dist/runtime/core/types/action.js +38 -0
  22. package/dist/runtime/core/types/model.d.ts +70 -0
  23. package/dist/runtime/core/types/model.js +5 -0
  24. package/dist/runtime/core/types/shape.d.ts +46 -0
  25. package/dist/runtime/core/types/shape.js +0 -0
  26. package/dist/runtime/core/types/view.d.ts +29 -0
  27. package/dist/runtime/core/types/view.js +0 -0
  28. package/dist/runtime/core/utils/action.d.ts +4 -0
  29. package/dist/runtime/core/utils/action.js +294 -0
  30. package/dist/runtime/core/utils/model.d.ts +12 -0
  31. package/dist/runtime/core/utils/model.js +224 -0
  32. package/dist/runtime/core/utils/shape.d.ts +3 -0
  33. package/dist/runtime/core/utils/shape.js +29 -0
  34. package/dist/runtime/core/utils/view.d.ts +5 -0
  35. package/dist/runtime/core/utils/view.js +19 -0
  36. package/dist/runtime/index.d.ts +9 -13
  37. package/dist/runtime/index.js +5 -7
  38. package/dist/runtime/plugin.js +2 -5
  39. package/package.json +5 -2
  40. package/dist/runtime/composables/use.d.ts +0 -30
  41. package/dist/runtime/composables/use.js +0 -25
  42. package/dist/runtime/core/adapter.d.ts +0 -33
  43. package/dist/runtime/core/adapter.js +0 -33
  44. package/dist/runtime/core/api.d.ts +0 -37
  45. package/dist/runtime/core/api.js +0 -62
  46. package/dist/runtime/core/errors.d.ts +0 -22
  47. package/dist/runtime/core/errors.js +0 -33
  48. package/dist/runtime/shared.d.ts +0 -9
  49. package/dist/runtime/shared.js +0 -3
  50. package/dist/runtime/utils/endpoint.d.ts +0 -40
  51. package/dist/runtime/utils/endpoint.js +0 -47
  52. package/dist/runtime/utils/schema.d.ts +0 -17
  53. package/dist/runtime/utils/schema.js +0 -26
  54. package/dist/runtime/utils/transform.d.ts +0 -6
  55. package/dist/runtime/utils/transform.js +0 -20
package/README.md CHANGED
@@ -1,159 +1,104 @@
1
1
  # Harlemify
2
2
 
3
- > Schema-driven state management for Nuxt powered by [Harlem](https://harlemjs.com/)
4
-
5
- ![Harlemify](https://raw.githubusercontent.com/diphyx/harlemify/main/docs/_media/icon.svg)
6
-
7
- Define your data schema once with Zod, and Harlemify handles the rest: type-safe API calls, reactive state, request monitoring, and automatic memory management. Your schema becomes the single source of truth for types, validation, and API payloads.
3
+ > Factory-driven state management for Nuxt powered by [Harlem](https://harlemjs.com/)
8
4
 
9
5
  ## Features
10
6
 
11
- - **Schema-Driven** - Zod schema defines types, validation, and API payloads
12
- - **Custom Adapters** - Pluggable HTTP adapters for custom request handling
13
- - **Reactive Memory** - Unit and collection caching with Vue reactivity
14
- - **Request Monitoring** - Track pending, success, and failed states
15
- - **SSR Support** - Server-side rendering via Harlem SSR plugin
7
+ - **Shape-Driven** - Zod shapes define types and identifiers
8
+ - **Three-Layer Architecture** - Model (state), View (computed), Action (async operations)
9
+ - **Chainable Action Builders** - Fluent `api`, `handle`, `commit` chains
10
+ - **Per-Action Status Tracking** - Built-in `loading`, `status`, `error`, `data` on every action
11
+ - **Concurrency Control** - Block, skip, cancel, or allow concurrent calls
12
+ - **SSR Support** - Server-side rendering with automatic hydration
16
13
 
17
- ## Installation
14
+ ## Install
18
15
 
19
16
  ```bash
20
17
  npm install @diphyx/harlemify
21
18
  ```
22
19
 
23
- ## Quick Start
20
+ ## Setup
24
21
 
25
22
  ```typescript
26
23
  // nuxt.config.ts
27
24
  export default defineNuxtConfig({
28
25
  modules: ["@diphyx/harlemify"],
29
26
  harlemify: {
30
- api: {
31
- adapter: {
32
- baseURL: "https://api.example.com",
33
- timeout: 10000,
34
- },
27
+ action: {
28
+ endpoint: "https://api.example.com",
35
29
  },
36
30
  },
37
31
  });
38
32
  ```
39
33
 
40
- ```typescript
41
- // stores/user.ts
42
- import { z } from "zod";
43
- import { createStore, Endpoint, EndpointMethod } from "@diphyx/harlemify";
44
-
45
- const UserSchema = z.object({
46
- id: z.number().meta({ indicator: true }),
47
- name: z.string().meta({
48
- methods: [EndpointMethod.POST, EndpointMethod.PATCH],
49
- }),
50
- });
51
-
52
- export type User = z.infer<typeof UserSchema>;
53
-
54
- export const userStore = createStore("user", UserSchema, {
55
- [Endpoint.GET_UNITS]: { method: EndpointMethod.GET, url: "/users" },
56
- [Endpoint.POST_UNITS]: { method: EndpointMethod.POST, url: "/users" },
57
- [Endpoint.PATCH_UNITS]: { method: EndpointMethod.PATCH, url: (p) => `/users/${p.id}` },
58
- [Endpoint.DELETE_UNITS]: { method: EndpointMethod.DELETE, url: (p) => `/users/${p.id}` },
59
- });
60
- ```
61
-
62
- ## Custom Adapters
63
-
64
- Harlemify supports custom HTTP adapters for advanced use cases like streaming responses, file uploads with progress, or custom authentication.
65
-
66
- ### Adapter Hierarchy
67
-
68
- Adapters are resolved in the following order (highest to lowest priority):
69
-
70
- 1. **Endpoint adapter** - Per-endpoint custom adapter
71
- 2. **Store adapter** - Store-level adapter option
72
- 3. **Module adapter** - Global config in `nuxt.config.ts`
73
- 4. **Default adapter** - Built-in fetch adapter
74
-
75
- ### Built-in Adapter
76
-
77
- Use `defineApiAdapter` to create an adapter with custom options:
34
+ ## Usage
78
35
 
79
36
  ```typescript
80
- import { defineApiAdapter } from "@diphyx/harlemify";
81
-
82
- const customAdapter = defineApiAdapter({
83
- baseURL: "/api",
84
- timeout: 5000,
85
- retry: 3,
86
- retryDelay: 1000,
87
- retryStatusCodes: [500, 502, 503],
37
+ // stores/user.ts
38
+ import { createStore, shape, ActionOneMode, ActionManyMode, type ShapeInfer } from "@diphyx/harlemify";
39
+
40
+ const userShape = shape((factory) => {
41
+ return {
42
+ id: factory.number().meta({
43
+ identifier: true,
44
+ }),
45
+ name: factory.string(),
46
+ email: factory.email(),
47
+ };
88
48
  });
89
- ```
90
-
91
- ### Custom Adapter
92
-
93
- Create a fully custom adapter for advanced scenarios:
94
-
95
- ```typescript
96
- import type { ApiAdapter, ApiAdapterRequest } from "@diphyx/harlemify";
97
-
98
- const streamingAdapter: ApiAdapter<MyType> = async (request: ApiAdapterRequest) => {
99
- // Custom fetch logic with streaming, progress, etc.
100
- const response = await fetch(request.url, {
101
- method: request.method,
102
- headers: request.headers,
103
- body: JSON.stringify(request.body),
104
- });
105
-
106
- const data = await response.json();
107
- return { data, status: response.status };
108
- };
109
- ```
110
-
111
- ### Using Adapters
112
49
 
113
- **Store-level adapter:**
50
+ export type User = ShapeInfer<typeof userShape>;
114
51
 
115
- ```typescript
116
- export const userStore = createStore(
117
- "user",
118
- UserSchema,
119
- {
120
- [Endpoint.GET_UNITS]: { method: EndpointMethod.GET, url: "/users" },
121
- },
122
- {
123
- adapter: customAdapter, // Used for all endpoints in this store
52
+ export const userStore = createStore({
53
+ name: "users",
54
+ model({ one, many }) {
55
+ return {
56
+ current: one(userShape),
57
+ list: many(userShape),
58
+ };
124
59
  },
125
- );
126
- ```
127
-
128
- **Endpoint-level adapter:**
129
-
130
- ```typescript
131
- export const userStore = createStore("user", UserSchema, {
132
- [Endpoint.GET_UNIT]: {
133
- method: EndpointMethod.GET,
134
- url: (p) => `/users/${p.id}`,
135
- adapter: detailAdapter, // Custom adapter for this endpoint only
60
+ view({ from }) {
61
+ return {
62
+ user: from("current"),
63
+ users: from("list"),
64
+ };
136
65
  },
137
- [Endpoint.GET_UNITS]: {
138
- method: EndpointMethod.GET,
139
- url: "/users",
140
- // Uses store or global adapter
66
+ action({ api, commit }) {
67
+ return {
68
+ list: api
69
+ .get({
70
+ url: "/users",
71
+ })
72
+ .commit("list", ActionManyMode.SET),
73
+ create: api
74
+ .post({
75
+ url: "/users",
76
+ })
77
+ .commit("list", ActionManyMode.ADD),
78
+ clear: commit("list", ActionManyMode.RESET),
79
+ };
141
80
  },
142
81
  });
143
82
  ```
144
83
 
145
- ## Why Harlemify?
84
+ ```vue
85
+ <script setup>
86
+ const { view, action } = userStore;
146
87
 
147
- | | |
148
- | --------------- | ------------------------------------------------- |
149
- | **Type-Safe** | Full TypeScript support with Zod schema inference |
150
- | **Declarative** | Define schema once, derive everything else |
151
- | **Reactive** | Powered by Vue's reactivity through Harlem |
152
- | **Extensible** | Custom adapters for any HTTP requirement |
88
+ await action.list();
89
+ </script>
90
+
91
+ <template>
92
+ <div v-if="action.list.loading.value">Loading...</div>
93
+ <ul v-else>
94
+ <li v-for="user in view.users.value" :key="user.id">{{ user.name }}</li>
95
+ </ul>
96
+ </template>
97
+ ```
153
98
 
154
99
  ## Documentation
155
100
 
156
- Full documentation available at [https://diphyx.github.io/harlemify/](https://diphyx.github.io/harlemify/)
101
+ [https://diphyx.github.io/harlemify/](https://diphyx.github.io/harlemify/)
157
102
 
158
103
  ## License
159
104
 
package/dist/module.d.mts CHANGED
@@ -1,22 +1,33 @@
1
1
  import * as _nuxt_schema from '@nuxt/schema';
2
2
 
3
- interface ApiFetchAdapterOptions {
4
- baseURL?: string;
3
+ interface RuntimeModelConfig {
4
+ identifier?: string;
5
+ }
6
+
7
+ interface RuntimeViewConfig {
8
+ }
9
+
10
+ interface RuntimeActionConfig {
11
+ endpoint?: string;
12
+ headers?: Record<string, string>;
13
+ query?: Record<string, unknown>;
5
14
  timeout?: number;
6
- retry?: number | false;
7
- retryDelay?: number;
8
- retryStatusCodes?: number[];
9
- responseType?: "json" | "text" | "blob" | "arrayBuffer";
15
+ concurrent?: ActionConcurrent;
16
+ }
17
+ declare enum ActionConcurrent {
18
+ BLOCK = "block",
19
+ SKIP = "skip",
20
+ CANCEL = "cancel",
21
+ ALLOW = "allow"
10
22
  }
11
23
 
12
- type SharedConfig = {
13
- api?: {
14
- headers?: Record<string, string>;
15
- query?: Record<string, unknown>;
16
- adapter?: ApiFetchAdapterOptions;
17
- };
24
+ type RuntimeConfig = {
25
+ model?: RuntimeModelConfig;
26
+ view?: RuntimeViewConfig;
27
+ action?: RuntimeActionConfig;
28
+ logger?: number;
18
29
  };
19
30
 
20
- declare const _default: _nuxt_schema.NuxtModule<SharedConfig, SharedConfig, false>;
31
+ declare const _default: _nuxt_schema.NuxtModule<RuntimeConfig, RuntimeConfig, false>;
21
32
 
22
33
  export { _default as default };
package/dist/module.d.ts CHANGED
@@ -1,22 +1,33 @@
1
1
  import * as _nuxt_schema from '@nuxt/schema';
2
2
 
3
- interface ApiFetchAdapterOptions {
4
- baseURL?: string;
3
+ interface RuntimeModelConfig {
4
+ identifier?: string;
5
+ }
6
+
7
+ interface RuntimeViewConfig {
8
+ }
9
+
10
+ interface RuntimeActionConfig {
11
+ endpoint?: string;
12
+ headers?: Record<string, string>;
13
+ query?: Record<string, unknown>;
5
14
  timeout?: number;
6
- retry?: number | false;
7
- retryDelay?: number;
8
- retryStatusCodes?: number[];
9
- responseType?: "json" | "text" | "blob" | "arrayBuffer";
15
+ concurrent?: ActionConcurrent;
16
+ }
17
+ declare enum ActionConcurrent {
18
+ BLOCK = "block",
19
+ SKIP = "skip",
20
+ CANCEL = "cancel",
21
+ ALLOW = "allow"
10
22
  }
11
23
 
12
- type SharedConfig = {
13
- api?: {
14
- headers?: Record<string, string>;
15
- query?: Record<string, unknown>;
16
- adapter?: ApiFetchAdapterOptions;
17
- };
24
+ type RuntimeConfig = {
25
+ model?: RuntimeModelConfig;
26
+ view?: RuntimeViewConfig;
27
+ action?: RuntimeActionConfig;
28
+ logger?: number;
18
29
  };
19
30
 
20
- declare const _default: _nuxt_schema.NuxtModule<SharedConfig, SharedConfig, false>;
31
+ declare const _default: _nuxt_schema.NuxtModule<RuntimeConfig, RuntimeConfig, false>;
21
32
 
22
33
  export { _default as default };
package/dist/module.json CHANGED
@@ -4,7 +4,7 @@
4
4
  "compatibility": {
5
5
  "nuxt": ">=3.0.0 || >=4.0.0"
6
6
  },
7
- "version": "2.0.0",
7
+ "version": "4.0.0",
8
8
  "builder": {
9
9
  "@nuxt/module-builder": "0.8.4",
10
10
  "unbuild": "unknown"
package/dist/module.mjs CHANGED
@@ -1,4 +1,4 @@
1
- import { defineNuxtModule, createResolver, addTemplate, addPlugin, addImportsDir } from '@nuxt/kit';
1
+ import { defineNuxtModule, createResolver, addTemplate, addPlugin, addImportsDir, addImports } from '@nuxt/kit';
2
2
 
3
3
  const module = defineNuxtModule({
4
4
  meta: {
@@ -8,13 +8,7 @@ const module = defineNuxtModule({
8
8
  nuxt: ">=3.0.0 || >=4.0.0"
9
9
  }
10
10
  },
11
- defaults: {
12
- api: {
13
- headers: {},
14
- query: {},
15
- adapter: {}
16
- }
17
- },
11
+ defaults: {},
18
12
  setup(options, nuxt) {
19
13
  const { resolve } = createResolver(import.meta.url);
20
14
  addTemplate({
@@ -25,9 +19,13 @@ const module = defineNuxtModule({
25
19
  }
26
20
  });
27
21
  addPlugin(resolve("./runtime", "plugin"));
28
- addImportsDir(resolve("./runtime", "core"));
29
22
  addImportsDir(resolve("./runtime", "composables"));
30
- addImportsDir(resolve("./runtime", "utils"));
23
+ addImports([
24
+ {
25
+ name: "createStore",
26
+ from: resolve("./runtime/core/store")
27
+ }
28
+ ]);
31
29
  nuxt.options.build.transpile.push(/@harlem\//);
32
30
  }
33
31
  });
@@ -0,0 +1,4 @@
1
+ import { type Ref } from "vue";
2
+ import { type ActionError, ActionStatus } from "../core/types/action.js";
3
+ export declare function useIsolatedActionStatus(): Ref<ActionStatus>;
4
+ export declare function useIsolatedActionError(): Ref<ActionError | null>;
@@ -0,0 +1,8 @@
1
+ import { ref } from "vue";
2
+ import { ActionStatus } from "../core/types/action.js";
3
+ export function useIsolatedActionStatus() {
4
+ return ref(ActionStatus.IDLE);
5
+ }
6
+ export function useIsolatedActionError() {
7
+ return ref(null);
8
+ }
@@ -0,0 +1,10 @@
1
+ import type { RuntimeModelConfig } from "./core/types/model.js";
2
+ import type { RuntimeViewConfig } from "./core/types/view.js";
3
+ import type { RuntimeActionConfig } from "./core/types/action.js";
4
+ export type RuntimeConfig = {
5
+ model?: RuntimeModelConfig;
6
+ view?: RuntimeViewConfig;
7
+ action?: RuntimeActionConfig;
8
+ logger?: number;
9
+ };
10
+ export declare const runtimeConfig: RuntimeConfig;
@@ -0,0 +1,7 @@
1
+ import config from "#build/harlemify.config";
2
+ export const runtimeConfig = {
3
+ model: config.model ?? {},
4
+ view: config.view ?? {},
5
+ action: config.action ?? {},
6
+ logger: config.logger ?? -999
7
+ };
@@ -0,0 +1,4 @@
1
+ import type { ConsolaInstance } from "consola";
2
+ import type { Model } from "../types/model.js";
3
+ import { type RuntimeActionConfig, type ActionFactory } from "../types/action.js";
4
+ export declare function createActionFactory<M extends Model, V>(config?: RuntimeActionConfig, logger?: ConsolaInstance, _model?: M, _view?: V): ActionFactory<M, V>;
@@ -0,0 +1,102 @@
1
+ import { buildCommitMethod } from "../utils/action.js";
2
+ import {
3
+ ActionApiMethod,
4
+ DEFINITION
5
+ } from "../types/action.js";
6
+ export function createActionFactory(config, logger, _model, _view) {
7
+ function apiCall(apiDefinition) {
8
+ apiDefinition = {
9
+ endpoint: config?.endpoint,
10
+ headers: config?.headers,
11
+ query: config?.query,
12
+ timeout: config?.timeout,
13
+ concurrent: config?.concurrent,
14
+ ...apiDefinition
15
+ };
16
+ const actionDefinition = {
17
+ api: apiDefinition,
18
+ logger
19
+ };
20
+ return {
21
+ handle(callback) {
22
+ const handleDefinition = {
23
+ api: apiDefinition,
24
+ handle: callback,
25
+ logger
26
+ };
27
+ return {
28
+ commit: buildCommitMethod(handleDefinition),
29
+ get [DEFINITION]() {
30
+ return handleDefinition;
31
+ }
32
+ };
33
+ },
34
+ commit: buildCommitMethod(actionDefinition),
35
+ get [DEFINITION]() {
36
+ return actionDefinition;
37
+ }
38
+ };
39
+ }
40
+ function apiGet(definition) {
41
+ return apiCall({
42
+ ...definition,
43
+ method: ActionApiMethod.GET
44
+ });
45
+ }
46
+ function apiHead(definition) {
47
+ return apiCall({
48
+ ...definition,
49
+ method: ActionApiMethod.HEAD
50
+ });
51
+ }
52
+ function apiPost(definition) {
53
+ return apiCall({
54
+ ...definition,
55
+ method: ActionApiMethod.POST
56
+ });
57
+ }
58
+ function apiPut(definition) {
59
+ return apiCall({
60
+ ...definition,
61
+ method: ActionApiMethod.PUT
62
+ });
63
+ }
64
+ function apiPatch(definition) {
65
+ return apiCall({
66
+ ...definition,
67
+ method: ActionApiMethod.PATCH
68
+ });
69
+ }
70
+ function apiDelete(definition) {
71
+ return apiCall({
72
+ ...definition,
73
+ method: ActionApiMethod.DELETE
74
+ });
75
+ }
76
+ const api = Object.assign(apiCall, {
77
+ get: apiGet,
78
+ head: apiHead,
79
+ post: apiPost,
80
+ put: apiPut,
81
+ patch: apiPatch,
82
+ delete: apiDelete
83
+ });
84
+ function handle(callback) {
85
+ const definition = {
86
+ handle: callback,
87
+ logger
88
+ };
89
+ return {
90
+ commit: buildCommitMethod(definition),
91
+ get [DEFINITION]() {
92
+ return definition;
93
+ }
94
+ };
95
+ }
96
+ const commit = buildCommitMethod({ logger });
97
+ return {
98
+ api,
99
+ handle,
100
+ commit
101
+ };
102
+ }
@@ -0,0 +1,3 @@
1
+ import type { ConsolaInstance } from "consola";
2
+ import { type RuntimeModelConfig, type ModelFactory } from "../types/model.js";
3
+ export declare function createModelFactory(config?: RuntimeModelConfig, logger?: ConsolaInstance): ModelFactory;
@@ -0,0 +1,31 @@
1
+ import {
2
+ ModelKind
3
+ } from "../types/model.js";
4
+ export function createModelFactory(config, logger) {
5
+ function one(shape, options) {
6
+ return {
7
+ shape,
8
+ kind: ModelKind.OBJECT,
9
+ options: {
10
+ identifier: config?.identifier,
11
+ ...options
12
+ },
13
+ logger
14
+ };
15
+ }
16
+ function many(shape, options) {
17
+ return {
18
+ shape,
19
+ kind: ModelKind.ARRAY,
20
+ options: {
21
+ identifier: config?.identifier,
22
+ ...options
23
+ },
24
+ logger
25
+ };
26
+ }
27
+ return {
28
+ one,
29
+ many
30
+ };
31
+ }
@@ -0,0 +1,45 @@
1
+ import { z } from "zod";
2
+ import type { ShapeFactory } from "../types/shape.js";
3
+ export declare const primitiveField: {
4
+ string: typeof z.string;
5
+ number: typeof z.number;
6
+ boolean: typeof z.boolean;
7
+ bigint: typeof z.bigint;
8
+ date: typeof z.date;
9
+ };
10
+ export declare const structureField: {
11
+ object: typeof z.object;
12
+ array: typeof z.array;
13
+ tuple: typeof z.tuple;
14
+ record: typeof z.record;
15
+ map: typeof z.map;
16
+ set: typeof z.set;
17
+ enum: typeof z.enum;
18
+ union: typeof z.union;
19
+ literal: typeof z.literal;
20
+ };
21
+ export declare const formatField: {
22
+ email: typeof z.email;
23
+ url: typeof z.url;
24
+ uuid: typeof z.uuid;
25
+ cuid: typeof z.cuid;
26
+ cuid2: typeof z.cuid2;
27
+ ulid: typeof z.ulid;
28
+ nanoid: typeof z.nanoid;
29
+ jwt: typeof z.jwt;
30
+ emoji: typeof z.emoji;
31
+ ipv4: typeof z.ipv4;
32
+ ipv6: typeof z.ipv6;
33
+ mac: typeof z.mac;
34
+ base64: typeof z.base64;
35
+ base64url: typeof z.base64url;
36
+ hex: typeof z.hex;
37
+ };
38
+ export declare const specialField: {
39
+ any: typeof z.any;
40
+ unknown: typeof z.unknown;
41
+ never: typeof z.never;
42
+ nullable: typeof z.nullable;
43
+ optional: typeof z.optional;
44
+ };
45
+ export declare function shape<T extends z.ZodRawShape>(definition: T | ((factory: ShapeFactory) => T)): z.ZodObject<T>;
@@ -0,0 +1,56 @@
1
+ import { z } from "zod";
2
+ export const primitiveField = {
3
+ string: z.string,
4
+ number: z.number,
5
+ boolean: z.boolean,
6
+ bigint: z.bigint,
7
+ date: z.date
8
+ };
9
+ export const structureField = {
10
+ object: z.object,
11
+ array: z.array,
12
+ tuple: z.tuple,
13
+ record: z.record,
14
+ map: z.map,
15
+ set: z.set,
16
+ enum: z.enum,
17
+ union: z.union,
18
+ literal: z.literal
19
+ };
20
+ export const formatField = {
21
+ email: z.email,
22
+ url: z.url,
23
+ uuid: z.uuid,
24
+ cuid: z.cuid,
25
+ cuid2: z.cuid2,
26
+ ulid: z.ulid,
27
+ nanoid: z.nanoid,
28
+ jwt: z.jwt,
29
+ emoji: z.emoji,
30
+ ipv4: z.ipv4,
31
+ ipv6: z.ipv6,
32
+ mac: z.mac,
33
+ base64: z.base64,
34
+ base64url: z.base64url,
35
+ hex: z.hex
36
+ };
37
+ export const specialField = {
38
+ any: z.any,
39
+ unknown: z.unknown,
40
+ never: z.never,
41
+ nullable: z.nullable,
42
+ optional: z.optional
43
+ };
44
+ export function shape(definition) {
45
+ if (typeof definition === "function") {
46
+ return z.object(
47
+ definition({
48
+ ...primitiveField,
49
+ ...structureField,
50
+ ...formatField,
51
+ ...specialField
52
+ })
53
+ );
54
+ }
55
+ return z.object(definition);
56
+ }
@@ -0,0 +1,4 @@
1
+ import type { ConsolaInstance } from "consola";
2
+ import type { Model } from "../types/model.js";
3
+ import type { RuntimeViewConfig, ViewFactory } from "../types/view.js";
4
+ export declare function createViewFactory<M extends Model>(config?: RuntimeViewConfig, logger?: ConsolaInstance, _model?: M): ViewFactory<M>;
@@ -0,0 +1,21 @@
1
+ export function createViewFactory(config, logger, _model) {
2
+ function from(source, resolver) {
3
+ const definition = {
4
+ sources: [source],
5
+ resolver,
6
+ logger
7
+ };
8
+ return definition;
9
+ }
10
+ function merge(sources, resolver) {
11
+ return {
12
+ sources,
13
+ resolver,
14
+ logger
15
+ };
16
+ }
17
+ return {
18
+ from,
19
+ merge
20
+ };
21
+ }