@hypen-space/core 0.2.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 (49) hide show
  1. package/dist/chunk-5va59f7m.js +22 -0
  2. package/dist/chunk-5va59f7m.js.map +9 -0
  3. package/dist/engine.d.ts +101 -0
  4. package/dist/events.d.ts +78 -0
  5. package/dist/index.browser.d.ts +13 -0
  6. package/dist/index.d.ts +33 -0
  7. package/dist/remote/index.d.ts +6 -0
  8. package/dist/router.d.ts +93 -0
  9. package/dist/src/app.js +160 -0
  10. package/dist/src/app.js.map +10 -0
  11. package/dist/src/context.js +114 -0
  12. package/dist/src/context.js.map +10 -0
  13. package/dist/src/engine.browser.js +130 -0
  14. package/dist/src/engine.browser.js.map +10 -0
  15. package/dist/src/engine.js +101 -0
  16. package/dist/src/engine.js.map +10 -0
  17. package/dist/src/events.js +72 -0
  18. package/dist/src/events.js.map +10 -0
  19. package/dist/src/index.browser.js +51 -0
  20. package/dist/src/index.browser.js.map +9 -0
  21. package/dist/src/index.js +55 -0
  22. package/dist/src/index.js.map +9 -0
  23. package/dist/src/remote/client.js +176 -0
  24. package/dist/src/remote/client.js.map +10 -0
  25. package/dist/src/remote/index.js +9 -0
  26. package/dist/src/remote/index.js.map +9 -0
  27. package/dist/src/remote/types.js +2 -0
  28. package/dist/src/remote/types.js.map +9 -0
  29. package/dist/src/renderer.js +58 -0
  30. package/dist/src/renderer.js.map +10 -0
  31. package/dist/src/router.js +189 -0
  32. package/dist/src/router.js.map +10 -0
  33. package/dist/src/state.js +226 -0
  34. package/dist/src/state.js.map +10 -0
  35. package/dist/state.d.ts +30 -0
  36. package/package.json +124 -0
  37. package/src/app.ts +330 -0
  38. package/src/context.ts +201 -0
  39. package/src/engine.browser.ts +245 -0
  40. package/src/engine.ts +208 -0
  41. package/src/events.ts +126 -0
  42. package/src/index.browser.ts +104 -0
  43. package/src/index.ts +126 -0
  44. package/src/remote/client.ts +274 -0
  45. package/src/remote/index.ts +17 -0
  46. package/src/remote/types.ts +51 -0
  47. package/src/renderer.ts +102 -0
  48. package/src/router.ts +311 -0
  49. package/src/state.ts +363 -0
@@ -0,0 +1,226 @@
1
+ import"../chunk-5va59f7m.js";
2
+
3
+ // src/state.ts
4
+ function deepClone(obj) {
5
+ if (obj === null || typeof obj !== "object") {
6
+ return obj;
7
+ }
8
+ const visited = new WeakMap;
9
+ function cloneInternal(value) {
10
+ if (value === null || typeof value !== "object") {
11
+ return value;
12
+ }
13
+ if (visited.has(value)) {
14
+ return visited.get(value);
15
+ }
16
+ if (value instanceof Date) {
17
+ return new Date(value.getTime());
18
+ }
19
+ if (value instanceof RegExp) {
20
+ return new RegExp(value.source, value.flags);
21
+ }
22
+ if (value instanceof Map) {
23
+ const mapClone = new Map;
24
+ visited.set(value, mapClone);
25
+ for (const [k, v] of value.entries()) {
26
+ mapClone.set(cloneInternal(k), cloneInternal(v));
27
+ }
28
+ return mapClone;
29
+ }
30
+ if (value instanceof Set) {
31
+ const setClone = new Set;
32
+ visited.set(value, setClone);
33
+ for (const item of value.values()) {
34
+ setClone.add(cloneInternal(item));
35
+ }
36
+ return setClone;
37
+ }
38
+ if (value instanceof WeakMap || value instanceof WeakSet) {
39
+ return value;
40
+ }
41
+ if (Array.isArray(value)) {
42
+ const arrClone = [];
43
+ visited.set(value, arrClone);
44
+ for (let i = 0;i < value.length; i++) {
45
+ arrClone[i] = cloneInternal(value[i]);
46
+ }
47
+ return arrClone;
48
+ }
49
+ const objClone = {};
50
+ visited.set(value, objClone);
51
+ for (const key in value) {
52
+ if (value.hasOwnProperty(key)) {
53
+ objClone[key] = cloneInternal(value[key]);
54
+ }
55
+ }
56
+ return objClone;
57
+ }
58
+ return cloneInternal(obj);
59
+ }
60
+ function diffState(oldState, newState, basePath = "") {
61
+ const paths = [];
62
+ const newValues = {};
63
+ function diff(oldVal, newVal, path) {
64
+ if (oldVal === newVal)
65
+ return;
66
+ if (typeof oldVal !== "object" || typeof newVal !== "object" || oldVal === null || newVal === null) {
67
+ if (oldVal !== newVal) {
68
+ paths.push(path);
69
+ newValues[path] = newVal;
70
+ }
71
+ return;
72
+ }
73
+ if (Array.isArray(oldVal) || Array.isArray(newVal)) {
74
+ if (!Array.isArray(oldVal) || !Array.isArray(newVal) || oldVal.length !== newVal.length) {
75
+ paths.push(path);
76
+ newValues[path] = newVal;
77
+ return;
78
+ }
79
+ for (let i = 0;i < newVal.length; i++) {
80
+ const itemPath = path ? `${path}.${i}` : `${i}`;
81
+ diff(oldVal[i], newVal[i], itemPath);
82
+ }
83
+ return;
84
+ }
85
+ const oldKeys = new Set(Object.keys(oldVal));
86
+ const newKeys = new Set(Object.keys(newVal));
87
+ for (const key of newKeys) {
88
+ const propPath = path ? `${path}.${key}` : key;
89
+ if (!oldKeys.has(key)) {
90
+ paths.push(propPath);
91
+ newValues[propPath] = newVal[key];
92
+ } else {
93
+ diff(oldVal[key], newVal[key], propPath);
94
+ }
95
+ }
96
+ for (const key of oldKeys) {
97
+ if (!newKeys.has(key)) {
98
+ const propPath = path ? `${path}.${key}` : key;
99
+ paths.push(propPath);
100
+ newValues[propPath] = undefined;
101
+ }
102
+ }
103
+ }
104
+ diff(oldState, newState, basePath);
105
+ return { paths, newValues };
106
+ }
107
+ function createObservableState(initialState, options) {
108
+ const opts = options || { onChange: () => {} };
109
+ if (initialState instanceof Number || initialState instanceof String || initialState instanceof Boolean) {
110
+ throw new TypeError("Cannot create observable state from primitive wrapper objects (Number, String, Boolean). " + "Use plain primitives or regular objects instead.");
111
+ }
112
+ let lastSnapshot = deepClone(initialState);
113
+ const pathPrefix = opts.pathPrefix || "";
114
+ let batchDepth = 0;
115
+ let pendingChange = null;
116
+ function notifyChange() {
117
+ if (batchDepth > 0)
118
+ return;
119
+ const change = diffState(lastSnapshot, state, pathPrefix);
120
+ if (change.paths.length > 0) {
121
+ lastSnapshot = deepClone(state);
122
+ if (pendingChange) {
123
+ change.paths.push(...pendingChange.paths);
124
+ Object.assign(change.newValues, pendingChange.newValues);
125
+ pendingChange = null;
126
+ }
127
+ opts.onChange(change);
128
+ }
129
+ }
130
+ let notificationPending = false;
131
+ function scheduleBatch() {
132
+ if (batchDepth === 0) {
133
+ if (!notificationPending) {
134
+ notificationPending = true;
135
+ queueMicrotask(() => {
136
+ notificationPending = false;
137
+ if (batchDepth === 0) {
138
+ notifyChange();
139
+ }
140
+ });
141
+ }
142
+ }
143
+ }
144
+ const proxyCache = new WeakMap;
145
+ function createProxy(target, basePath) {
146
+ if (proxyCache.has(target)) {
147
+ return proxyCache.get(target);
148
+ }
149
+ const proxy = new Proxy(target, {
150
+ get(obj, prop) {
151
+ const value = obj[prop];
152
+ if (prop === "__beginBatch") {
153
+ return () => {
154
+ batchDepth++;
155
+ };
156
+ }
157
+ if (prop === "__endBatch") {
158
+ return () => {
159
+ batchDepth--;
160
+ if (batchDepth === 0) {
161
+ notifyChange();
162
+ }
163
+ };
164
+ }
165
+ if (prop === "__getSnapshot") {
166
+ return () => deepClone(obj);
167
+ }
168
+ if (value && typeof value === "object") {
169
+ if (value instanceof Date || value instanceof RegExp || value instanceof Map || value instanceof Set || value instanceof WeakMap || value instanceof WeakSet) {
170
+ return value;
171
+ }
172
+ return createProxy(value, basePath ? `${basePath}.${String(prop)}` : String(prop));
173
+ }
174
+ return value;
175
+ },
176
+ set(obj, prop, value) {
177
+ const oldValue = obj[prop];
178
+ obj[prop] = value;
179
+ if (oldValue !== value) {
180
+ scheduleBatch();
181
+ }
182
+ return true;
183
+ },
184
+ deleteProperty(obj, prop) {
185
+ if (prop in obj) {
186
+ delete obj[prop];
187
+ scheduleBatch();
188
+ }
189
+ return true;
190
+ }
191
+ });
192
+ proxyCache.set(target, proxy);
193
+ return proxy;
194
+ }
195
+ const state = createProxy(initialState, pathPrefix);
196
+ return state;
197
+ }
198
+ function batchStateUpdates(state, fn) {
199
+ const s = state;
200
+ if (s.__beginBatch && s.__endBatch) {
201
+ s.__beginBatch();
202
+ try {
203
+ fn();
204
+ } finally {
205
+ s.__endBatch();
206
+ }
207
+ } else {
208
+ fn();
209
+ }
210
+ }
211
+ function getStateSnapshot(state) {
212
+ const s = state;
213
+ if (s.__getSnapshot) {
214
+ return s.__getSnapshot();
215
+ }
216
+ return deepClone(state);
217
+ }
218
+ export {
219
+ getStateSnapshot,
220
+ createObservableState,
221
+ batchStateUpdates
222
+ };
223
+
224
+ export { createObservableState, batchStateUpdates, getStateSnapshot };
225
+
226
+ //# debugId=22E8D2156028037264756E2164756E21
@@ -0,0 +1,10 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/state.ts"],
4
+ "sourcesContent": [
5
+ "/**\n * State management with observer pattern and diffing\n */\n\nexport type StatePath = string; // e.g., \"user.name\", \"items.0.title\"\n\n/**\n * Represents a change in state with full path information\n */\nexport interface StateChange {\n paths: StatePath[];\n newValues: Record<StatePath, any>;\n}\n\n/**\n * Options for state observer\n */\nexport interface StateObserverOptions {\n onChange: (change: StateChange) => void;\n pathPrefix?: string; // For nested observers\n}\n\n/**\n * Deep clone an object, handling circular references\n */\nfunction deepClone<T>(obj: T): T {\n // Handle primitives and null\n if (obj === null || typeof obj !== 'object') {\n return obj;\n }\n\n // Use a WeakMap to track visited objects and handle circular references\n const visited = new WeakMap();\n\n function cloneInternal(value: any): any {\n // Handle primitives and null\n if (value === null || typeof value !== 'object') {\n return value;\n }\n\n // Check if we've already cloned this object (circular reference)\n if (visited.has(value)) {\n return visited.get(value);\n }\n\n // Handle Date\n if (value instanceof Date) {\n return new Date(value.getTime());\n }\n\n // Handle RegExp\n if (value instanceof RegExp) {\n return new RegExp(value.source, value.flags);\n }\n\n // Handle Map\n if (value instanceof Map) {\n const mapClone = new Map();\n visited.set(value, mapClone);\n for (const [k, v] of value.entries()) {\n mapClone.set(cloneInternal(k), cloneInternal(v));\n }\n return mapClone;\n }\n\n // Handle Set\n if (value instanceof Set) {\n const setClone = new Set();\n visited.set(value, setClone);\n for (const item of value.values()) {\n setClone.add(cloneInternal(item));\n }\n return setClone;\n }\n\n // Handle WeakMap/WeakSet - cannot be cloned, return as-is\n if (value instanceof WeakMap || value instanceof WeakSet) {\n return value;\n }\n\n // Handle Array\n if (Array.isArray(value)) {\n const arrClone: any[] = [];\n visited.set(value, arrClone);\n for (let i = 0; i < value.length; i++) {\n arrClone[i] = cloneInternal(value[i]);\n }\n return arrClone;\n }\n\n // Handle plain objects\n const objClone: any = {};\n visited.set(value, objClone);\n for (const key in value) {\n if (value.hasOwnProperty(key)) {\n objClone[key] = cloneInternal(value[key]);\n }\n }\n return objClone;\n }\n\n return cloneInternal(obj);\n}\n\n/**\n * Compare two values and detect changes with full paths\n */\nfunction diffState(\n oldState: any,\n newState: any,\n basePath: string = \"\"\n): StateChange {\n const paths: StatePath[] = [];\n const newValues: Record<StatePath, any> = {};\n\n function diff(oldVal: any, newVal: any, path: string) {\n // Handle null/undefined\n if (oldVal === newVal) return;\n\n // Different types or primitives\n if (\n typeof oldVal !== \"object\" ||\n typeof newVal !== \"object\" ||\n oldVal === null ||\n newVal === null\n ) {\n if (oldVal !== newVal) {\n paths.push(path);\n newValues[path] = newVal;\n }\n return;\n }\n\n // Arrays\n if (Array.isArray(oldVal) || Array.isArray(newVal)) {\n if (\n !Array.isArray(oldVal) ||\n !Array.isArray(newVal) ||\n oldVal.length !== newVal.length\n ) {\n paths.push(path);\n newValues[path] = newVal;\n return;\n }\n\n for (let i = 0; i < newVal.length; i++) {\n const itemPath = path ? `${path}.${i}` : `${i}`;\n diff(oldVal[i], newVal[i], itemPath);\n }\n return;\n }\n\n // Objects\n const oldKeys = new Set(Object.keys(oldVal));\n const newKeys = new Set(Object.keys(newVal));\n\n // Check for added or changed keys\n for (const key of newKeys) {\n const propPath = path ? `${path}.${key}` : key;\n if (!oldKeys.has(key)) {\n // New property\n paths.push(propPath);\n newValues[propPath] = newVal[key];\n } else {\n // Existing property, recurse\n diff(oldVal[key], newVal[key], propPath);\n }\n }\n\n // Check for removed keys\n for (const key of oldKeys) {\n if (!newKeys.has(key)) {\n const propPath = path ? `${path}.${key}` : key;\n paths.push(propPath);\n newValues[propPath] = undefined;\n }\n }\n }\n\n diff(oldState, newState, basePath);\n return { paths, newValues };\n}\n\n/**\n * Create an observable state object that tracks changes\n */\nexport function createObservableState<T extends object>(\n initialState: T,\n options?: StateObserverOptions\n): T {\n // Use default options if not provided\n const opts: StateObserverOptions = options || { onChange: () => {} };\n\n // Detect and reject primitive wrapper objects (Number, String, Boolean)\n if (\n initialState instanceof Number ||\n initialState instanceof String ||\n initialState instanceof Boolean\n ) {\n throw new TypeError(\n \"Cannot create observable state from primitive wrapper objects (Number, String, Boolean). \" +\n \"Use plain primitives or regular objects instead.\"\n );\n }\n\n // Keep a snapshot of the last known state\n let lastSnapshot = deepClone(initialState);\n const pathPrefix = opts.pathPrefix || \"\";\n\n // Track if we're in a batch update\n let batchDepth = 0;\n let pendingChange: StateChange | null = null;\n\n function notifyChange() {\n if (batchDepth > 0) return;\n\n // Compare current state with last snapshot\n const change = diffState(lastSnapshot, state, pathPrefix);\n\n if (change.paths.length > 0) {\n // Update snapshot\n lastSnapshot = deepClone(state);\n\n // Merge with pending changes if any\n if (pendingChange) {\n change.paths.push(...pendingChange.paths);\n Object.assign(change.newValues, pendingChange.newValues);\n pendingChange = null;\n }\n\n // Notify\n opts.onChange(change);\n }\n }\n\n // Track if we have a pending microtask notification\n let notificationPending = false;\n\n function scheduleBatch() {\n if (batchDepth === 0) {\n // If not in a batch, schedule notification in next microtask to coalesce rapid changes\n if (!notificationPending) {\n notificationPending = true;\n queueMicrotask(() => {\n notificationPending = false;\n if (batchDepth === 0) {\n notifyChange();\n }\n });\n }\n }\n }\n\n // Cache proxies to handle circular references\n const proxyCache = new WeakMap<any, any>();\n\n function createProxy(target: any, basePath: string): any {\n // Return cached proxy if it exists (handles circular references)\n if (proxyCache.has(target)) {\n return proxyCache.get(target);\n }\n\n const proxy = new Proxy(target, {\n get(obj, prop) {\n const value = obj[prop];\n\n // Expose batch control methods\n if (prop === \"__beginBatch\") {\n return () => {\n batchDepth++;\n };\n }\n if (prop === \"__endBatch\") {\n return () => {\n batchDepth--;\n if (batchDepth === 0) {\n notifyChange();\n }\n };\n }\n if (prop === \"__getSnapshot\") {\n return () => deepClone(obj);\n }\n\n // Return proxied nested objects/arrays, but NOT special types\n if (value && typeof value === \"object\") {\n // Check for special object types that should not be proxied\n if (\n value instanceof Date ||\n value instanceof RegExp ||\n value instanceof Map ||\n value instanceof Set ||\n value instanceof WeakMap ||\n value instanceof WeakSet\n ) {\n return value;\n }\n\n // Proxy regular objects and arrays\n return createProxy(value, basePath ? `${basePath}.${String(prop)}` : String(prop));\n }\n\n return value;\n },\n\n set(obj, prop, value) {\n const oldValue = obj[prop];\n\n // Set the new value\n obj[prop] = value;\n\n if (oldValue !== value) {\n scheduleBatch();\n }\n\n return true;\n },\n\n deleteProperty(obj, prop) {\n if (prop in obj) {\n delete obj[prop];\n scheduleBatch();\n }\n return true;\n },\n });\n\n // Cache the proxy before returning\n proxyCache.set(target, proxy);\n return proxy;\n }\n\n const state = createProxy(initialState, pathPrefix);\n return state as T;\n}\n\n/**\n * Helper to batch multiple state updates\n */\nexport function batchStateUpdates<T>(state: T, fn: () => void): void {\n const s = state as any;\n if (s.__beginBatch && s.__endBatch) {\n s.__beginBatch();\n try {\n fn();\n } finally {\n s.__endBatch();\n }\n } else {\n fn();\n }\n}\n\n/**\n * Get a snapshot of the current state\n */\nexport function getStateSnapshot<T>(state: T): T {\n const s = state as any;\n if (s.__getSnapshot) {\n return s.__getSnapshot();\n }\n return deepClone(state);\n}\n"
6
+ ],
7
+ "mappings": "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",
8
+ "debugId": "22E8D2156028037264756E2164756E21",
9
+ "names": []
10
+ }
@@ -0,0 +1,30 @@
1
+ /**
2
+ * State management with observer pattern and diffing
3
+ */
4
+ export declare type StatePath = string;
5
+ /**
6
+ * Represents a change in state with full path information
7
+ */
8
+ export interface StateChange {
9
+ paths: StatePath[];
10
+ newValues: Record<StatePath, any>;
11
+ }
12
+ /**
13
+ * Options for state observer
14
+ */
15
+ export interface StateObserverOptions {
16
+ onChange: (change: StateChange) => void;
17
+ pathPrefix?: string;
18
+ }
19
+ /**
20
+ * Create an observable state object that tracks changes
21
+ */
22
+ export declare function createObservableState<T extends object>(initialState: T, options?: StateObserverOptions): T;
23
+ /**
24
+ * Helper to batch multiple state updates
25
+ */
26
+ export declare function batchStateUpdates<T>(state: T, fn: () => void): void;
27
+ /**
28
+ * Get a snapshot of the current state
29
+ */
30
+ export declare function getStateSnapshot<T>(state: T): T;
package/package.json ADDED
@@ -0,0 +1,124 @@
1
+ {
2
+ "name": "@hypen-space/core",
3
+ "version": "0.2.0",
4
+ "description": "Hypen core engine - Platform-agnostic reactive UI runtime",
5
+ "type": "module",
6
+ "main": "./dist/index.js",
7
+ "module": "./dist/index.js",
8
+ "types": "./dist/index.d.ts",
9
+ "exports": {
10
+ ".": {
11
+ "types": "./dist/index.d.ts",
12
+ "browser": "./dist/index.browser.js",
13
+ "bun": "./src/index.ts",
14
+ "node": "./dist/index.js",
15
+ "import": "./dist/index.js",
16
+ "default": "./dist/index.js"
17
+ },
18
+ "./engine": {
19
+ "types": "./dist/engine.d.ts",
20
+ "browser": "./dist/engine.browser.js",
21
+ "bun": "./src/engine.ts",
22
+ "node": "./dist/engine.js",
23
+ "import": "./dist/engine.js",
24
+ "default": "./dist/engine.js"
25
+ },
26
+ "./engine/browser": {
27
+ "types": "./dist/engine.browser.d.ts",
28
+ "browser": "./dist/engine.browser.js",
29
+ "bun": "./src/engine.browser.ts",
30
+ "import": "./dist/engine.browser.js",
31
+ "default": "./dist/engine.browser.js"
32
+ },
33
+ "./app": {
34
+ "types": "./dist/app.d.ts",
35
+ "bun": "./src/app.ts",
36
+ "import": "./dist/app.js",
37
+ "default": "./dist/app.js"
38
+ },
39
+ "./state": {
40
+ "types": "./dist/state.d.ts",
41
+ "bun": "./src/state.ts",
42
+ "import": "./dist/state.js",
43
+ "default": "./dist/state.js"
44
+ },
45
+ "./renderer": {
46
+ "types": "./dist/renderer.d.ts",
47
+ "bun": "./src/renderer.ts",
48
+ "import": "./dist/renderer.js",
49
+ "default": "./dist/renderer.js"
50
+ },
51
+ "./router": {
52
+ "types": "./dist/router.d.ts",
53
+ "bun": "./src/router.ts",
54
+ "import": "./dist/router.js",
55
+ "default": "./dist/router.js"
56
+ },
57
+ "./events": {
58
+ "types": "./dist/events.d.ts",
59
+ "bun": "./src/events.ts",
60
+ "import": "./dist/events.js",
61
+ "default": "./dist/events.js"
62
+ },
63
+ "./context": {
64
+ "types": "./dist/context.d.ts",
65
+ "bun": "./src/context.ts",
66
+ "import": "./dist/context.js",
67
+ "default": "./dist/context.js"
68
+ },
69
+ "./remote": {
70
+ "types": "./dist/remote/index.d.ts",
71
+ "bun": "./src/remote/index.ts",
72
+ "import": "./dist/remote/index.js",
73
+ "default": "./dist/remote/index.js"
74
+ },
75
+ "./remote/client": {
76
+ "types": "./dist/remote/client.d.ts",
77
+ "bun": "./src/remote/client.ts",
78
+ "import": "./dist/remote/client.js",
79
+ "default": "./dist/remote/client.js"
80
+ }
81
+ },
82
+ "files": [
83
+ "dist",
84
+ "src",
85
+ "wasm"
86
+ ],
87
+ "scripts": {
88
+ "build": "bun run build.ts",
89
+ "build:types": "tsc --emitDeclarationOnly",
90
+ "typecheck": "tsc --noEmit",
91
+ "clean": "rm -rf dist"
92
+ },
93
+ "dependencies": {},
94
+ "devDependencies": {
95
+ "@types/bun": "latest",
96
+ "typescript": "^5"
97
+ },
98
+ "peerDependencies": {
99
+ "typescript": "^5"
100
+ },
101
+ "peerDependenciesMeta": {
102
+ "typescript": {
103
+ "optional": true
104
+ }
105
+ },
106
+ "keywords": [
107
+ "hypen",
108
+ "ui",
109
+ "declarative",
110
+ "reactive",
111
+ "wasm",
112
+ "engine"
113
+ ],
114
+ "engines": {
115
+ "node": ">=18.0.0"
116
+ },
117
+ "author": "Ian Rumac",
118
+ "license": "MIT",
119
+ "repository": {
120
+ "type": "git",
121
+ "url": "https://github.com/hypen-lang/hypen-engine-rs.git",
122
+ "directory": "hypen-render-bun/packages/core"
123
+ }
124
+ }