@shahwali/archangel 0.0.3 → 0.0.4

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.md CHANGED
@@ -1,171 +1,195 @@
1
- # Archangel
2
-
3
- A small library for building web-based desktop applications in Zig.
4
-
5
- ## Creating an Archangel Application
6
-
7
- ### Prerequisites
8
-
9
- - Zig compiler, version **0.15.2** or higher
10
- - Platform specific dependencies
11
- - Windows
12
- - WebView2
13
- - Linux
14
- - webkit2gtk-4.1
15
- - MacOS
16
- - WebKit
17
-
18
- There is currently no CLI or similar tooling for bootstrapping an Archangel application. You will need to do the following steps manually.
19
-
20
- ### Initialize a New Project
21
-
22
- You can bring your own frontend setup for your Archangel application, but below steps will assume you are using Vite as your build tool.
23
-
24
- Create your Vite project
25
-
26
- ```sh
27
- # or npm, yarn, pnpm e.t.c
28
- $ bun create vite
29
- $ cd <app-name>
30
- $ bun add @shahwali/archangel
31
- ```
32
-
33
- Create your archangel source directory inside the project
34
-
35
- ```sh
36
- $ mkdir src-archangel
37
- $ cd src-archangel
38
- $ zig init --minimal
39
- $ zig fetch --save git+https://codeberg.org/shahwali/archangel.git
40
- ```
41
-
42
- Archangel is quite flexible in how you want to use it, but an `archangel.conf.zon` file is required to configure the application. Place it in src-archangel with the following content.
43
-
44
- ```
45
- .{
46
- .app_name = "My Example App",
47
- .dev_url = "http://localhost:5173/", // Must be the same as the url your are hosting your frontend on locally.
48
- .frontend_build_path = "../dist", // Must be the same as the path your frontend is built to.
49
- .window = .{
50
- .width = 1280,
51
- .height = 720,
52
- .title = "My App",
53
- },
54
- }
55
- ```
56
-
57
- For a simple minimal Archangel application, you can create the following `main.zig` file in the `src-archangel/src`.
58
-
59
- ```zig
60
- const std = @import("std");
61
- const archangel = @import("archangel");
62
-
63
- const HelloResponse = struct {
64
- message: []const u8,
65
- timestamp: i64,
66
- };
67
-
68
- fn helloHandler(name: []const u8) !HelloResponse {
69
- if (std.mem.eql(u8, name, "John")) {
70
- return error.InvalidName;
71
- }
72
-
73
- return HelloResponse{
74
- .message = try std.fmt.allocPrint(std.heap.page_allocator, "Hello, {s}!", .{name}),
75
- .timestamp = std.time.timestamp(),
76
- };
77
- }
78
-
79
- pub fn main() !void {
80
- // Use whatever allocator you want.
81
- var gpa = std.heap.DebugAllocator(.{ .safety = true }).init;
82
- const allocator = gpa.allocator();
83
-
84
- defer {
85
- if (gpa.deinit() == .leak) {
86
- @panic("memory leak detected!");
87
- }
88
- }
89
-
90
- var app = try archangel.App.init(
91
- allocator,
92
- .{
93
- .{ "hello", archangel.handler.create(helloHandler) },
94
- },
95
- );
96
- defer app.deinit();
97
-
98
- try app.run();
99
- }
100
- ```
101
-
102
- And then you can build it with the following `build.zig`
103
-
104
- ```zig
105
- const std = @import("std");
106
- const archangel = @import("archangel");
107
-
108
- pub fn build(b: *std.Build) void {
109
- const target = b.standardTargetOptions(.{
110
- .default_target = .{
111
- .cpu_model = .baseline,
112
- },
113
- });
114
- const optimize = b.standardOptimizeOption(.{});
115
-
116
- const exe, const archangel_dep = archangel.createApp(b, .{
117
- .exe_name = "testapp",
118
- .exe_create_options = .{
119
- .target = target,
120
- .optimize = optimize,
121
- .root_source_file = b.path("src/main.zig"),
122
- },
123
- });
124
-
125
- exe.root_module.addImport("archangel", archangel_dep.module("archangel"));
126
- }
127
- ```
128
-
129
- The `archangel.createApp` function will create an executable with the given config, and create a `run` step that you can use to run the application. It also creates an option `dev` which can be passed to enable development mode. In development mode, the webview will navigate to the `dev_url` you specified in the archange.conf.zon file, rather than embedding the frontend in the binary, thus allowing you to take advantage of HMR-like features with a tool like Vite for example.
130
-
131
- For a more advanced example, you can look at [the testapp example](examples/testapp/src-archangel). This example shows a more realistic use case of archangel, where your app is contained to a Zig module which is then imported in your executable entry point. The module can then have its own tests and be self contained.
132
-
133
- ### Run the application in development mode
134
-
135
- In the frontend root, start the dev server
136
-
137
- ```sh
138
- $ bun dev
139
- ```
140
-
141
- In the archangel root (src-archangel), start the application.
142
-
143
- ```sh
144
- $ zig build run -Ddev
145
- ```
146
-
147
- ### Build the application for production
148
-
149
- In the frontend root, build the production version of the frontend
150
-
151
- ```sh
152
- $ bun run build
153
- ```
154
-
155
- In the archangel root (src-archangel), build the application.
156
-
157
- ```sh
158
- $ zig build
159
- ```
160
-
161
- You will find the executable in the `zig-out/bin` directory.
162
-
163
- You can also run the application to test it in production mode
164
-
165
- ```sh
166
- $ zig build run
167
- ```
168
-
169
- ### Bundling
170
-
171
- Archangel does not come with a bundler, although it is planned to add one in the future. For now, you will have to manually bundle your application using whatever tool your prefer for your designated platform. Luckily, the Zig build system is quite powerful and one can easily modify the `build.zig` to do all kinds of things, such as installing additional binaries, libraries, assets and resources alongside your application executable. You can then use a tool like WiX on Windows or hdiutil on macOS to create an installer for your application.
1
+ # Archangel
2
+
3
+ A small library for building web-based desktop applications in Zig.
4
+
5
+ ## Creating an Archangel Application
6
+
7
+ ### Prerequisites
8
+
9
+ - Zig compiler, version **0.15.2** or higher
10
+ - Platform specific dependencies
11
+ - Windows
12
+ - WebView2
13
+ - Linux
14
+ - webkit2gtk-4.1
15
+ - MacOS
16
+ - WebKit
17
+
18
+ There is currently no CLI or similar tooling for bootstrapping an Archangel application. You will need to do the following steps manually.
19
+
20
+ ### Initialize a New Project
21
+
22
+ You can bring your own frontend setup for your Archangel application, but below steps will assume you are using Vite as your build tool.
23
+
24
+ Create your Vite project
25
+
26
+ ```sh
27
+ # or npm, yarn, pnpm e.t.c
28
+ $ bun create vite
29
+ $ cd <app-name>
30
+ $ bun add @shahwali/archangel
31
+ ```
32
+
33
+ Create your archangel source directory inside the project
34
+
35
+ ```sh
36
+ $ mkdir src-archangel
37
+ $ cd src-archangel
38
+ $ zig init --minimal
39
+ $ zig fetch --save git+https://codeberg.org/shahwali/archangel.git
40
+ ```
41
+
42
+ Archangel is quite flexible in how you want to use it, but an `archangel.conf.zon` file is required to configure the application. Place it in src-archangel with the following content.
43
+
44
+ ```
45
+ .{
46
+ .app_name = "My Example App",
47
+ .dev_url = "http://localhost:5173/", // Must be the same as the url your are hosting your frontend on locally.
48
+ .frontend_build_path = "../dist", // Must be the same as the path your frontend is built to.
49
+ .bindings_path = "../src/generated",
50
+ .window = .{
51
+ .width = 1280,
52
+ .height = 720,
53
+ .title = "My App",
54
+ },
55
+ }
56
+ ```
57
+
58
+ For a simple minimal Archangel application, you can create the following `main.zig` file in the `src-archangel/src`.
59
+
60
+ ```zig
61
+ const std = @import("std");
62
+ const archangel = @import("archangel");
63
+
64
+ const HelloResponse = struct {
65
+ message: []const u8,
66
+ timestamp: i64,
67
+ };
68
+
69
+ fn helloHandler(name: []const u8) !HelloResponse {
70
+ if (std.mem.eql(u8, name, "John")) {
71
+ return error.InvalidName;
72
+ }
73
+
74
+ return HelloResponse{
75
+ .message = try std.fmt.allocPrint(std.heap.page_allocator, "Hello, {s}!", .{name}),
76
+ .timestamp = std.time.timestamp(),
77
+ };
78
+ }
79
+
80
+ pub fn main() !void {
81
+ // Use whatever allocator you want.
82
+ var gpa = std.heap.DebugAllocator(.{ .safety = true }).init;
83
+ const allocator = gpa.allocator();
84
+
85
+ defer {
86
+ if (gpa.deinit() == .leak) {
87
+ @panic("memory leak detected!");
88
+ }
89
+ }
90
+
91
+ var app = try archangel.App.init(
92
+ allocator,
93
+ .{
94
+ .{ "hello", archangel.handler.create(helloHandler) },
95
+ },
96
+ );
97
+ defer app.deinit();
98
+
99
+ try app.run();
100
+ }
101
+ ```
102
+
103
+ And then you can build it with the following `build.zig`
104
+
105
+ ```zig
106
+ const std = @import("std");
107
+ const archangel = @import("archangel");
108
+
109
+ pub fn build(b: *std.Build) void {
110
+ const target = b.standardTargetOptions(.{
111
+ .default_target = .{
112
+ .cpu_model = .baseline,
113
+ },
114
+ });
115
+ const optimize = b.standardOptimizeOption(.{});
116
+
117
+ const exe, const archangel_dep = archangel.createApp(b, .{
118
+ .exe_name = "testapp",
119
+ .exe_create_options = .{
120
+ .target = target,
121
+ .optimize = optimize,
122
+ .root_source_file = b.path("src/main.zig"),
123
+ },
124
+ });
125
+
126
+ exe.root_module.addImport("archangel", archangel_dep.module("archangel"));
127
+ }
128
+ ```
129
+
130
+ The `archangel.createApp` function will create an executable with the given config, and create a `run` step that you can use to run the application. It also creates an option `dev` which can be passed to enable development mode. In development mode, the webview will navigate to the `dev_url` you specified in the archange.conf.zon file, rather than embedding the frontend in the binary, thus allowing you to take advantage of HMR-like features with a tool like Vite for example.
131
+
132
+ For a more advanced example, you can look at [the testapp example](examples/testapp/src-archangel). This example shows a more realistic use case of archangel, where your app is contained to a Zig module which is then imported in your executable entry point. The module can then have its own tests and be self contained.
133
+
134
+ ### Run the application in development mode
135
+
136
+ In the frontend root, start the dev server
137
+
138
+ ```sh
139
+ $ bun dev
140
+ ```
141
+
142
+ In the archangel root (src-archangel), start the application.
143
+
144
+ ```sh
145
+ $ zig build run -Ddev
146
+ ```
147
+
148
+ ### Build the application for production
149
+
150
+ In the frontend root, build the production version of the frontend
151
+
152
+ ```sh
153
+ $ bun run build
154
+ ```
155
+
156
+ In the archangel root (src-archangel), build the application.
157
+
158
+ ```sh
159
+ $ zig build
160
+ ```
161
+
162
+ You will find the executable in the `zig-out/bin` directory.
163
+
164
+ You can also run the application to test it in production mode
165
+
166
+ ```sh
167
+ $ zig build run
168
+ ```
169
+
170
+ ## Bundling
171
+
172
+ Archangel does not come with a bundler, although it is planned to add one in the future. For now, you will have to manually bundle your application using whatever tool your prefer for your designated platform. Luckily, the Zig build system is quite powerful and one can easily modify the `build.zig` to do all kinds of things, such as installing additional binaries, libraries, assets and resources alongside your application executable. You can then use a tool like WiX on Windows or hdiutil on macOS to create an installer for your application.
173
+
174
+ ## Experimental Features
175
+
176
+ ### Generate typescript bindings
177
+
178
+ You can generate typescript bindings for your handlers using the bindings step. To do this you must create an `archangel_options` declaration in your entry point file.
179
+
180
+ ```zig
181
+ const testapp = @import("testapp");
182
+ const archangel = @import("archangel");
183
+
184
+ pub const archangel_options: archangel.Options(testapp.handlers) = .{
185
+ .skip_binding = .initComptime(.{.{"hello"}}), // You can also specify handlers to skip/ignore.
186
+ };
187
+
188
+ pub fn main() !void ....
189
+ ```
190
+
191
+ ```sh
192
+ $ zig build bindings
193
+ ```
194
+
195
+ This will place the bindings in the `bindings_path` specified in your `archangel.conf.zon`.
@@ -3,9 +3,9 @@
3
3
  "sources": ["..\\src\\internal\\binding.ts", "..\\src\\index.ts"],
4
4
  "sourcesContent": [
5
5
  "export interface BindingError {\n __archangel_error: string;\n __archangel_error_trace?: string;\n}\n\nexport function isBindingError(result: any): result is BindingError {\n if (result === null || typeof result !== \"object\") {\n return false;\n }\n\n return \"__archangel_error\" in result && typeof result.__archangel_error === \"string\";\n}\n\nexport function throwBindingError(error: BindingError): never {\n throw new Error(error.__archangel_error, {\n cause:\n error.__archangel_error_trace ?? new Error(\"Error trace only available in debug builds.\"),\n });\n}\n\nexport function handleBindingResult<T>(result: any): T {\n if (isBindingError(result)) {\n throwBindingError(result);\n }\n return result as T;\n}\n\ntype BindingFn<TArgs = any, TResult = any> = (args: TArgs) => Promise<TResult>;\n\nexport function createBinding<TArgs, TResult>(windowKey: string): BindingFn<TArgs, TResult> {\n const fn = (window as any)[windowKey];\n\n if (!fn) {\n console.warn(`Backend binding not available: ${windowKey}`);\n }\n\n return async (args: TArgs) => {\n if (!fn) {\n throw new Error(`Backend binding not available: ${windowKey}`);\n }\n\n const result = await fn(args);\n return handleBindingResult(result);\n };\n}\n",
6
- "import { createBinding } from \"./internal/binding\";\n\ntype InvokeRequest = {\n function: string;\n args: string;\n};\n\nexport type InvokeArgs = Record<string, any>;\n\nconst _invoke = createBinding<InvokeRequest, any>(\"__invoke__\");\n\nexport interface InvokeHandlers {}\n\n// Helper type to check if args is empty object, null, undefined, or void\ntype IsEmptyArgs<T> =\n T extends Record<string, never> ? true : T extends null | undefined | void ? true : false;\n\n/**\n * Type-safe invoke method for calling backend functions\n */\nexport async function invoke<K extends keyof InvokeHandlers>(\n functionName: K,\n ...args: IsEmptyArgs<InvokeHandlers[K][\"args\"]> extends true\n ? [args?: InvokeHandlers[K][\"args\"]]\n : [args: InvokeHandlers[K][\"args\"]]\n): Promise<InvokeHandlers[K][\"result\"]>;\n\n// Fallback overload for when InvokeHandlers is empty or for dynamic usage\nexport async function invoke<T = any>(functionName: string, args?: any): Promise<T>;\n\nexport async function invoke(functionName: string, args: any = {}): Promise<any> {\n return _invoke({\n function: functionName,\n args: JSON.stringify(args),\n });\n}\n\ntype Listener<T = any> = (payload: T) => void;\n\nconst listeners = new Map<string, Set<Listener>>();\n\n/**\n * Subscribe to events emitted from the backend\n * @param event - Name of the event to listen for\n * @param cb - Callback function to execute when the event is emitted\n * @returns Unsubscribe function to stop listening to the event\n */\nexport function on<T = any>(event: string, cb: Listener<T>) {\n let set = listeners.get(event);\n if (!set) {\n set = new Set();\n listeners.set(event, set);\n }\n\n set.add(cb);\n\n return () => {\n set!.delete(cb);\n if (set!.size === 0) listeners.delete(event);\n };\n}\n\n/**\n * Subscribe to events emitted from the backend (fires only once)\n * @param event - Name of the event to listen for\n * @param cb - Callback function to execute when the event is emitted\n * @returns Unsubscribe function to stop listening to the event\n */\nexport function once<T = any>(event: string, cb: Listener<T>) {\n const wrappedCallback: Listener<T> = (payload) => {\n cb(payload);\n unsubscribe();\n };\n\n const unsubscribe = on(event, wrappedCallback);\n\n return unsubscribe;\n}\n\nfunction emit<T = any>(event: string, payload: T) {\n const set = listeners.get(event);\n if (!set) return;\n for (const cb of set) cb(payload);\n}\n\nObject.defineProperty(window, \"__emit__\", {\n value: emit,\n writable: false,\n configurable: false,\n});\n\nexport type { InvokeRequest, Listener };\n"
6
+ "import { createBinding } from \"./internal/binding\";\n\ntype InvokeRequest = {\n function: string;\n args: string;\n};\n\nexport type InvokeArgs = Record<string, any>;\n\nconst _invoke = createBinding<InvokeRequest, any>(\"__invoke__\");\n\nexport interface InvokeHandlers {}\n\ntype IsEmptyArgs<T> =\n T extends Record<string, never> ? true : T extends null | undefined | void ? true : false;\n\n/**\n * Generic invoke method for calling backend functions\n * @param functionName - Name of the backend function to call\n * @param args - Arguments to pass to the function\n * @returns Promise resolving to the result\n * Type-safe invoke method for calling backend functions\n */\nexport async function invoke<K extends keyof InvokeHandlers>(\n functionName: K,\n ...args: IsEmptyArgs<InvokeHandlers[K][\"args\"]> extends true\n ? [args?: InvokeHandlers[K][\"args\"]]\n : [args: InvokeHandlers[K][\"args\"]]\n): Promise<InvokeHandlers[K][\"result\"]>;\n\n// Fallback overload for when InvokeHandlers is empty or for dynamic usage\nexport async function invoke<T = any>(functionName: string, args?: any): Promise<T>;\n\nexport async function invoke(functionName: string, args: any = {}): Promise<any> {\n return _invoke({\n function: functionName,\n args: JSON.stringify(args),\n });\n}\n\ntype Listener<T = any> = (payload: T) => void;\n\nconst listeners = new Map<string, Set<Listener>>();\n\n/**\n * Subscribe to events emitted from the backend\n * @param event - Name of the event to listen for\n * @param cb - Callback function to execute when the event is emitted\n * @returns Unsubscribe function to stop listening to the event\n */\nexport function on<T = any>(event: string, cb: Listener<T>) {\n let set = listeners.get(event);\n if (!set) {\n set = new Set();\n listeners.set(event, set);\n }\n\n set.add(cb);\n\n return () => {\n set!.delete(cb);\n if (set!.size === 0) listeners.delete(event);\n };\n}\n\n/**\n * Subscribe to events emitted from the backend (fires only once)\n * @param event - Name of the event to listen for\n * @param cb - Callback function to execute when the event is emitted\n * @returns Unsubscribe function to stop listening to the event\n */\nexport function once<T = any>(event: string, cb: Listener<T>) {\n const wrappedCallback: Listener<T> = (payload) => {\n cb(payload);\n unsubscribe();\n };\n\n const unsubscribe = on(event, wrappedCallback);\n\n return unsubscribe;\n}\n\nfunction emit<T = any>(event: string, payload: T) {\n const set = listeners.get(event);\n if (!set) return;\n for (const cb of set) cb(payload);\n}\n\nObject.defineProperty(window, \"__emit__\", {\n value: emit,\n writable: false,\n configurable: false,\n});\n\nexport type { InvokeRequest, Listener };\n"
7
7
  ],
8
- "mappings": ";0kBAKO,SAAS,CAAc,CAAC,EAAqC,CAClE,GAAI,IAAW,MAAQ,OAAO,IAAW,SACvC,MAAO,GAGT,MAAO,sBAAuB,GAAU,OAAO,EAAO,oBAAsB,SAGvE,SAAS,CAAiB,CAAC,EAA4B,CAC5D,MAAU,MAAM,EAAM,kBAAmB,CACvC,MACE,EAAM,yBAA+B,MAAM,6CAA6C,CAC5F,CAAC,EAGI,SAAS,CAAsB,CAAC,EAAgB,CACrD,GAAI,EAAe,CAAM,EACvB,EAAkB,CAAM,EAE1B,OAAO,EAKF,SAAS,CAA6B,CAAC,EAA8C,CAC1F,IAAM,EAAM,OAAe,GAE3B,GAAI,CAAC,EACH,QAAQ,KAAK,kCAAkC,GAAW,EAG5D,MAAO,OAAO,IAAgB,CAC5B,GAAI,CAAC,EACH,MAAU,MAAM,kCAAkC,GAAW,EAG/D,IAAM,EAAS,MAAM,EAAG,CAAI,EAC5B,OAAO,EAAoB,CAAM,GCjCrC,IAAM,EAAU,EAAkC,YAAY,EAqB9D,eAAsB,CAAM,CAAC,EAAsB,EAAY,CAAC,EAAiB,CAC/E,OAAO,EAAQ,CACb,SAAU,EACV,KAAM,KAAK,UAAU,CAAI,CAC3B,CAAC,EAKH,IAAM,EAAY,IAAI,IAQf,SAAS,CAAW,CAAC,EAAe,EAAiB,CAC1D,IAAI,EAAM,EAAU,IAAI,CAAK,EAC7B,GAAI,CAAC,EACH,EAAM,IAAI,IACV,EAAU,IAAI,EAAO,CAAG,EAK1B,OAFA,EAAI,IAAI,CAAE,EAEH,IAAM,CAEX,GADA,EAAK,OAAO,CAAE,EACV,EAAK,OAAS,EAAG,EAAU,OAAO,CAAK,GAUxC,SAAS,CAAa,CAAC,EAAe,EAAiB,CAM5D,IAAM,EAAc,EAAG,EALc,CAAC,IAAY,CAChD,EAAG,CAAO,EACV,EAAY,EAG+B,EAE7C,OAAO,EAGT,SAAS,CAAa,CAAC,EAAe,EAAY,CAChD,IAAM,EAAM,EAAU,IAAI,CAAK,EAC/B,GAAI,CAAC,EAAK,OACV,QAAW,KAAM,EAAK,EAAG,CAAO,EAGlC,OAAO,eAAe,OAAQ,WAAY,CACxC,MAAO,EACP,SAAU,GACV,aAAc,EAChB,CAAC",
8
+ "mappings": ";0kBAKO,SAAS,CAAc,CAAC,EAAqC,CAClE,GAAI,IAAW,MAAQ,OAAO,IAAW,SACvC,MAAO,GAGT,MAAO,sBAAuB,GAAU,OAAO,EAAO,oBAAsB,SAGvE,SAAS,CAAiB,CAAC,EAA4B,CAC5D,MAAU,MAAM,EAAM,kBAAmB,CACvC,MACE,EAAM,yBAA+B,MAAM,6CAA6C,CAC5F,CAAC,EAGI,SAAS,CAAsB,CAAC,EAAgB,CACrD,GAAI,EAAe,CAAM,EACvB,EAAkB,CAAM,EAE1B,OAAO,EAKF,SAAS,CAA6B,CAAC,EAA8C,CAC1F,IAAM,EAAM,OAAe,GAE3B,GAAI,CAAC,EACH,QAAQ,KAAK,kCAAkC,GAAW,EAG5D,MAAO,OAAO,IAAgB,CAC5B,GAAI,CAAC,EACH,MAAU,MAAM,kCAAkC,GAAW,EAG/D,IAAM,EAAS,MAAM,EAAG,CAAI,EAC5B,OAAO,EAAoB,CAAM,GCjCrC,IAAM,EAAU,EAAkC,YAAY,EAwB9D,eAAsB,CAAM,CAAC,EAAsB,EAAY,CAAC,EAAiB,CAC/E,OAAO,EAAQ,CACb,SAAU,EACV,KAAM,KAAK,UAAU,CAAI,CAC3B,CAAC,EAKH,IAAM,EAAY,IAAI,IAQf,SAAS,CAAW,CAAC,EAAe,EAAiB,CAC1D,IAAI,EAAM,EAAU,IAAI,CAAK,EAC7B,GAAI,CAAC,EACH,EAAM,IAAI,IACV,EAAU,IAAI,EAAO,CAAG,EAK1B,OAFA,EAAI,IAAI,CAAE,EAEH,IAAM,CAEX,GADA,EAAK,OAAO,CAAE,EACV,EAAK,OAAS,EAAG,EAAU,OAAO,CAAK,GAUxC,SAAS,CAAa,CAAC,EAAe,EAAiB,CAM5D,IAAM,EAAc,EAAG,EALc,CAAC,IAAY,CAChD,EAAG,CAAO,EACV,EAAY,EAG+B,EAE7C,OAAO,EAGT,SAAS,CAAa,CAAC,EAAe,EAAY,CAChD,IAAM,EAAM,EAAU,IAAI,CAAK,EAC/B,GAAI,CAAC,EAAK,OACV,QAAW,KAAM,EAAK,EAAG,CAAO,EAGlC,OAAO,eAAe,OAAQ,WAAY,CACxC,MAAO,EACP,SAAU,GACV,aAAc,EAChB,CAAC",
9
9
  "debugId": "A5594DDE138E4E6D64756E2164756E21",
10
10
  "names": []
11
11
  }
package/dist/index.d.ts CHANGED
@@ -7,6 +7,10 @@ export interface InvokeHandlers {
7
7
  }
8
8
  type IsEmptyArgs<T> = T extends Record<string, never> ? true : T extends null | undefined | void ? true : false;
9
9
  /**
10
+ * Generic invoke method for calling backend functions
11
+ * @param functionName - Name of the backend function to call
12
+ * @param args - Arguments to pass to the function
13
+ * @returns Promise resolving to the result
10
14
  * Type-safe invoke method for calling backend functions
11
15
  */
12
16
  export declare function invoke<K extends keyof InvokeHandlers>(functionName: K, ...args: IsEmptyArgs<InvokeHandlers[K]["args"]> extends true ? [args?: InvokeHandlers[K]["args"]] : [args: InvokeHandlers[K]["args"]]): Promise<InvokeHandlers[K]["result"]>;
package/dist/index.js.map CHANGED
@@ -3,9 +3,9 @@
3
3
  "sources": ["..\\src\\internal\\binding.ts", "..\\src\\index.ts"],
4
4
  "sourcesContent": [
5
5
  "export interface BindingError {\n __archangel_error: string;\n __archangel_error_trace?: string;\n}\n\nexport function isBindingError(result: any): result is BindingError {\n if (result === null || typeof result !== \"object\") {\n return false;\n }\n\n return \"__archangel_error\" in result && typeof result.__archangel_error === \"string\";\n}\n\nexport function throwBindingError(error: BindingError): never {\n throw new Error(error.__archangel_error, {\n cause:\n error.__archangel_error_trace ?? new Error(\"Error trace only available in debug builds.\"),\n });\n}\n\nexport function handleBindingResult<T>(result: any): T {\n if (isBindingError(result)) {\n throwBindingError(result);\n }\n return result as T;\n}\n\ntype BindingFn<TArgs = any, TResult = any> = (args: TArgs) => Promise<TResult>;\n\nexport function createBinding<TArgs, TResult>(windowKey: string): BindingFn<TArgs, TResult> {\n const fn = (window as any)[windowKey];\n\n if (!fn) {\n console.warn(`Backend binding not available: ${windowKey}`);\n }\n\n return async (args: TArgs) => {\n if (!fn) {\n throw new Error(`Backend binding not available: ${windowKey}`);\n }\n\n const result = await fn(args);\n return handleBindingResult(result);\n };\n}\n",
6
- "import { createBinding } from \"./internal/binding\";\n\ntype InvokeRequest = {\n function: string;\n args: string;\n};\n\nexport type InvokeArgs = Record<string, any>;\n\nconst _invoke = createBinding<InvokeRequest, any>(\"__invoke__\");\n\nexport interface InvokeHandlers {}\n\n// Helper type to check if args is empty object, null, undefined, or void\ntype IsEmptyArgs<T> =\n T extends Record<string, never> ? true : T extends null | undefined | void ? true : false;\n\n/**\n * Type-safe invoke method for calling backend functions\n */\nexport async function invoke<K extends keyof InvokeHandlers>(\n functionName: K,\n ...args: IsEmptyArgs<InvokeHandlers[K][\"args\"]> extends true\n ? [args?: InvokeHandlers[K][\"args\"]]\n : [args: InvokeHandlers[K][\"args\"]]\n): Promise<InvokeHandlers[K][\"result\"]>;\n\n// Fallback overload for when InvokeHandlers is empty or for dynamic usage\nexport async function invoke<T = any>(functionName: string, args?: any): Promise<T>;\n\nexport async function invoke(functionName: string, args: any = {}): Promise<any> {\n return _invoke({\n function: functionName,\n args: JSON.stringify(args),\n });\n}\n\ntype Listener<T = any> = (payload: T) => void;\n\nconst listeners = new Map<string, Set<Listener>>();\n\n/**\n * Subscribe to events emitted from the backend\n * @param event - Name of the event to listen for\n * @param cb - Callback function to execute when the event is emitted\n * @returns Unsubscribe function to stop listening to the event\n */\nexport function on<T = any>(event: string, cb: Listener<T>) {\n let set = listeners.get(event);\n if (!set) {\n set = new Set();\n listeners.set(event, set);\n }\n\n set.add(cb);\n\n return () => {\n set!.delete(cb);\n if (set!.size === 0) listeners.delete(event);\n };\n}\n\n/**\n * Subscribe to events emitted from the backend (fires only once)\n * @param event - Name of the event to listen for\n * @param cb - Callback function to execute when the event is emitted\n * @returns Unsubscribe function to stop listening to the event\n */\nexport function once<T = any>(event: string, cb: Listener<T>) {\n const wrappedCallback: Listener<T> = (payload) => {\n cb(payload);\n unsubscribe();\n };\n\n const unsubscribe = on(event, wrappedCallback);\n\n return unsubscribe;\n}\n\nfunction emit<T = any>(event: string, payload: T) {\n const set = listeners.get(event);\n if (!set) return;\n for (const cb of set) cb(payload);\n}\n\nObject.defineProperty(window, \"__emit__\", {\n value: emit,\n writable: false,\n configurable: false,\n});\n\nexport type { InvokeRequest, Listener };\n"
6
+ "import { createBinding } from \"./internal/binding\";\n\ntype InvokeRequest = {\n function: string;\n args: string;\n};\n\nexport type InvokeArgs = Record<string, any>;\n\nconst _invoke = createBinding<InvokeRequest, any>(\"__invoke__\");\n\nexport interface InvokeHandlers {}\n\ntype IsEmptyArgs<T> =\n T extends Record<string, never> ? true : T extends null | undefined | void ? true : false;\n\n/**\n * Generic invoke method for calling backend functions\n * @param functionName - Name of the backend function to call\n * @param args - Arguments to pass to the function\n * @returns Promise resolving to the result\n * Type-safe invoke method for calling backend functions\n */\nexport async function invoke<K extends keyof InvokeHandlers>(\n functionName: K,\n ...args: IsEmptyArgs<InvokeHandlers[K][\"args\"]> extends true\n ? [args?: InvokeHandlers[K][\"args\"]]\n : [args: InvokeHandlers[K][\"args\"]]\n): Promise<InvokeHandlers[K][\"result\"]>;\n\n// Fallback overload for when InvokeHandlers is empty or for dynamic usage\nexport async function invoke<T = any>(functionName: string, args?: any): Promise<T>;\n\nexport async function invoke(functionName: string, args: any = {}): Promise<any> {\n return _invoke({\n function: functionName,\n args: JSON.stringify(args),\n });\n}\n\ntype Listener<T = any> = (payload: T) => void;\n\nconst listeners = new Map<string, Set<Listener>>();\n\n/**\n * Subscribe to events emitted from the backend\n * @param event - Name of the event to listen for\n * @param cb - Callback function to execute when the event is emitted\n * @returns Unsubscribe function to stop listening to the event\n */\nexport function on<T = any>(event: string, cb: Listener<T>) {\n let set = listeners.get(event);\n if (!set) {\n set = new Set();\n listeners.set(event, set);\n }\n\n set.add(cb);\n\n return () => {\n set!.delete(cb);\n if (set!.size === 0) listeners.delete(event);\n };\n}\n\n/**\n * Subscribe to events emitted from the backend (fires only once)\n * @param event - Name of the event to listen for\n * @param cb - Callback function to execute when the event is emitted\n * @returns Unsubscribe function to stop listening to the event\n */\nexport function once<T = any>(event: string, cb: Listener<T>) {\n const wrappedCallback: Listener<T> = (payload) => {\n cb(payload);\n unsubscribe();\n };\n\n const unsubscribe = on(event, wrappedCallback);\n\n return unsubscribe;\n}\n\nfunction emit<T = any>(event: string, payload: T) {\n const set = listeners.get(event);\n if (!set) return;\n for (const cb of set) cb(payload);\n}\n\nObject.defineProperty(window, \"__emit__\", {\n value: emit,\n writable: false,\n configurable: false,\n});\n\nexport type { InvokeRequest, Listener };\n"
7
7
  ],
8
- "mappings": ";AAKO,SAAS,CAAc,CAAC,EAAqC,CAClE,GAAI,IAAW,MAAQ,OAAO,IAAW,SACvC,MAAO,GAGT,MAAO,sBAAuB,GAAU,OAAO,EAAO,oBAAsB,SAGvE,SAAS,CAAiB,CAAC,EAA4B,CAC5D,MAAU,MAAM,EAAM,kBAAmB,CACvC,MACE,EAAM,yBAA+B,MAAM,6CAA6C,CAC5F,CAAC,EAGI,SAAS,CAAsB,CAAC,EAAgB,CACrD,GAAI,EAAe,CAAM,EACvB,EAAkB,CAAM,EAE1B,OAAO,EAKF,SAAS,CAA6B,CAAC,EAA8C,CAC1F,IAAM,EAAM,OAAe,GAE3B,GAAI,CAAC,EACH,QAAQ,KAAK,kCAAkC,GAAW,EAG5D,MAAO,OAAO,IAAgB,CAC5B,GAAI,CAAC,EACH,MAAU,MAAM,kCAAkC,GAAW,EAG/D,IAAM,EAAS,MAAM,EAAG,CAAI,EAC5B,OAAO,EAAoB,CAAM,GCjCrC,IAAM,EAAU,EAAkC,YAAY,EAqB9D,eAAsB,CAAM,CAAC,EAAsB,EAAY,CAAC,EAAiB,CAC/E,OAAO,EAAQ,CACb,SAAU,EACV,KAAM,KAAK,UAAU,CAAI,CAC3B,CAAC,EAKH,IAAM,EAAY,IAAI,IAQf,SAAS,CAAW,CAAC,EAAe,EAAiB,CAC1D,IAAI,EAAM,EAAU,IAAI,CAAK,EAC7B,GAAI,CAAC,EACH,EAAM,IAAI,IACV,EAAU,IAAI,EAAO,CAAG,EAK1B,OAFA,EAAI,IAAI,CAAE,EAEH,IAAM,CAEX,GADA,EAAK,OAAO,CAAE,EACV,EAAK,OAAS,EAAG,EAAU,OAAO,CAAK,GAUxC,SAAS,CAAa,CAAC,EAAe,EAAiB,CAM5D,IAAM,EAAc,EAAG,EALc,CAAC,IAAY,CAChD,EAAG,CAAO,EACV,EAAY,EAG+B,EAE7C,OAAO,EAGT,SAAS,CAAa,CAAC,EAAe,EAAY,CAChD,IAAM,EAAM,EAAU,IAAI,CAAK,EAC/B,GAAI,CAAC,EAAK,OACV,QAAW,KAAM,EAAK,EAAG,CAAO,EAGlC,OAAO,eAAe,OAAQ,WAAY,CACxC,MAAO,EACP,SAAU,GACV,aAAc,EAChB,CAAC",
8
+ "mappings": ";AAKO,SAAS,CAAc,CAAC,EAAqC,CAClE,GAAI,IAAW,MAAQ,OAAO,IAAW,SACvC,MAAO,GAGT,MAAO,sBAAuB,GAAU,OAAO,EAAO,oBAAsB,SAGvE,SAAS,CAAiB,CAAC,EAA4B,CAC5D,MAAU,MAAM,EAAM,kBAAmB,CACvC,MACE,EAAM,yBAA+B,MAAM,6CAA6C,CAC5F,CAAC,EAGI,SAAS,CAAsB,CAAC,EAAgB,CACrD,GAAI,EAAe,CAAM,EACvB,EAAkB,CAAM,EAE1B,OAAO,EAKF,SAAS,CAA6B,CAAC,EAA8C,CAC1F,IAAM,EAAM,OAAe,GAE3B,GAAI,CAAC,EACH,QAAQ,KAAK,kCAAkC,GAAW,EAG5D,MAAO,OAAO,IAAgB,CAC5B,GAAI,CAAC,EACH,MAAU,MAAM,kCAAkC,GAAW,EAG/D,IAAM,EAAS,MAAM,EAAG,CAAI,EAC5B,OAAO,EAAoB,CAAM,GCjCrC,IAAM,EAAU,EAAkC,YAAY,EAwB9D,eAAsB,CAAM,CAAC,EAAsB,EAAY,CAAC,EAAiB,CAC/E,OAAO,EAAQ,CACb,SAAU,EACV,KAAM,KAAK,UAAU,CAAI,CAC3B,CAAC,EAKH,IAAM,EAAY,IAAI,IAQf,SAAS,CAAW,CAAC,EAAe,EAAiB,CAC1D,IAAI,EAAM,EAAU,IAAI,CAAK,EAC7B,GAAI,CAAC,EACH,EAAM,IAAI,IACV,EAAU,IAAI,EAAO,CAAG,EAK1B,OAFA,EAAI,IAAI,CAAE,EAEH,IAAM,CAEX,GADA,EAAK,OAAO,CAAE,EACV,EAAK,OAAS,EAAG,EAAU,OAAO,CAAK,GAUxC,SAAS,CAAa,CAAC,EAAe,EAAiB,CAM5D,IAAM,EAAc,EAAG,EALc,CAAC,IAAY,CAChD,EAAG,CAAO,EACV,EAAY,EAG+B,EAE7C,OAAO,EAGT,SAAS,CAAa,CAAC,EAAe,EAAY,CAChD,IAAM,EAAM,EAAU,IAAI,CAAK,EAC/B,GAAI,CAAC,EAAK,OACV,QAAW,KAAM,EAAK,EAAG,CAAO,EAGlC,OAAO,eAAe,OAAQ,WAAY,CACxC,MAAO,EACP,SAAU,GACV,aAAc,EAChB,CAAC",
9
9
  "debugId": "4D4982FD20E292DC64756E2164756E21",
10
10
  "names": []
11
11
  }
@@ -0,0 +1,5 @@
1
+ // @bun @bun-cjs
2
+ (function(exports, require, module, __filename, __dirname) {var{defineProperty:o,getOwnPropertyNames:e,getOwnPropertyDescriptor:g}=Object,c=Object.prototype.hasOwnProperty;var t=new WeakMap,l=(r)=>{var n=t.get(r),i;if(n)return n;if(n=o({},"__esModule",{value:!0}),r&&typeof r==="object"||typeof r==="function")e(r).map((a)=>!c.call(n,a)&&o(n,a,{get:()=>r[a],enumerable:!(i=g(r,a))||i.enumerable}));return t.set(r,n),n};var s=(r,n)=>{for(var i in n)o(r,i,{get:n[i],enumerable:!0,configurable:!0,set:(a)=>n[i]=()=>a})};var h={};s(h,{run:()=>d});module.exports=l(h);function f(r){if(r===null||typeof r!=="object")return!1;return"__archangel_error"in r&&typeof r.__archangel_error==="string"}function T(r){throw Error(r.__archangel_error,{cause:r.__archangel_error_trace??Error("Error trace only available in debug builds.")})}function B(r){if(f(r))T(r);return r}function _(r){let n=window[r];if(!n)console.warn(`Backend binding not available: ${r}`);return async(i)=>{if(!n)throw Error(`Backend binding not available: ${r}`);let a=await n(i);return B(a)}}var E=_("__plugin_process_run__"),d=(r,n)=>E({argv:r,...n?{cwd:n.cwd,env:n.env?Object.entries(n.env).map(([i,a])=>({key:i,value:a})):void 0}:{}});})
3
+
4
+ //# debugId=76A3F262EB1AF98F64756E2164756E21
5
+ //# sourceMappingURL=index.cjs.map
@@ -0,0 +1,11 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["..\\src\\internal\\binding.ts", "..\\src\\plugins\\process\\index.ts"],
4
+ "sourcesContent": [
5
+ "export interface BindingError {\n __archangel_error: string;\n __archangel_error_trace?: string;\n}\n\nexport function isBindingError(result: any): result is BindingError {\n if (result === null || typeof result !== \"object\") {\n return false;\n }\n\n return \"__archangel_error\" in result && typeof result.__archangel_error === \"string\";\n}\n\nexport function throwBindingError(error: BindingError): never {\n throw new Error(error.__archangel_error, {\n cause:\n error.__archangel_error_trace ?? new Error(\"Error trace only available in debug builds.\"),\n });\n}\n\nexport function handleBindingResult<T>(result: any): T {\n if (isBindingError(result)) {\n throwBindingError(result);\n }\n return result as T;\n}\n\ntype BindingFn<TArgs = any, TResult = any> = (args: TArgs) => Promise<TResult>;\n\nexport function createBinding<TArgs, TResult>(windowKey: string): BindingFn<TArgs, TResult> {\n const fn = (window as any)[windowKey];\n\n if (!fn) {\n console.warn(`Backend binding not available: ${windowKey}`);\n }\n\n return async (args: TArgs) => {\n if (!fn) {\n throw new Error(`Backend binding not available: ${windowKey}`);\n }\n\n const result = await fn(args);\n return handleBindingResult(result);\n };\n}\n",
6
+ "import { createBinding } from \"../../internal/binding\";\r\n\r\ntype EnvMapping = {\r\n key: string;\r\n value: string;\r\n};\r\n\r\ntype RunRequestBinding = {\r\n argv: string[];\r\n cwd?: string;\r\n env?: EnvMapping[];\r\n};\r\n\r\n\r\nexport type RunRequest = {\r\n cwd?: string;\r\n env?: Record<string, string>;\r\n};\r\n\r\nexport type RunResponse = {\r\n stdout: string;\r\n stderr: string;\r\n term: number;\r\n};\r\n\r\nconst runBinding = createBinding<RunRequestBinding, RunResponse>(\"__plugin_process_run__\");\r\n\r\n/**\r\n * Run a command\r\n * @param args - Object containing the command arguments, current working directory, and environment variables\r\n * @returns Promise resolving to the run response\r\n */\r\nexport const run = (argv: string[], req?: RunRequest) => runBinding({\r\n argv: argv,\r\n ...req ? {\r\n cwd: req.cwd,\r\n env: req.env ? Object.entries(req.env).map(([key, value]) => ({ key, value })) : undefined,\r\n } : {},\r\n});\r\n"
7
+ ],
8
+ "mappings": ";mjBAKO,SAAS,CAAc,CAAC,EAAqC,CAClE,GAAI,IAAW,MAAQ,OAAO,IAAW,SACvC,MAAO,GAGT,MAAO,sBAAuB,GAAU,OAAO,EAAO,oBAAsB,SAGvE,SAAS,CAAiB,CAAC,EAA4B,CAC5D,MAAU,MAAM,EAAM,kBAAmB,CACvC,MACE,EAAM,yBAA+B,MAAM,6CAA6C,CAC5F,CAAC,EAGI,SAAS,CAAsB,CAAC,EAAgB,CACrD,GAAI,EAAe,CAAM,EACvB,EAAkB,CAAM,EAE1B,OAAO,EAKF,SAAS,CAA6B,CAAC,EAA8C,CAC1F,IAAM,EAAM,OAAe,GAE3B,GAAI,CAAC,EACH,QAAQ,KAAK,kCAAkC,GAAW,EAG5D,MAAO,OAAO,IAAgB,CAC5B,GAAI,CAAC,EACH,MAAU,MAAM,kCAAkC,GAAW,EAG/D,IAAM,EAAS,MAAM,EAAG,CAAI,EAC5B,OAAO,EAAoB,CAAM,GCjBrC,IAAM,EAAa,EAA8C,wBAAwB,EAO5E,EAAM,CAAC,EAAgB,IAAqB,EAAW,CAClE,KAAM,KACH,EAAM,CACP,IAAK,EAAI,IACT,IAAK,EAAI,IAAM,OAAO,QAAQ,EAAI,GAAG,EAAE,IAAI,EAAE,EAAK,MAAY,CAAE,MAAK,OAAM,EAAE,EAAI,MACnF,EAAI,CAAC,CACP,CAAC",
9
+ "debugId": "76A3F262EB1AF98F64756E2164756E21",
10
+ "names": []
11
+ }
@@ -0,0 +1,19 @@
1
+ export type RunRequest = {
2
+ cwd?: string;
3
+ env?: Record<string, string>;
4
+ };
5
+ export type RunResponse = {
6
+ stdout: string;
7
+ stderr: string;
8
+ term: number;
9
+ };
10
+ /**
11
+ * Run a command
12
+ * @param argv: Array of command arguments
13
+ * @param req: Optional request object containing the current working directory and environment variables
14
+ * @returns Promise resolving to the run response
15
+ */
16
+ export declare const run: (
17
+ argv: string[],
18
+ req?: RunRequest,
19
+ ) => Promise<RunResponse>;
@@ -0,0 +1,5 @@
1
+ // @bun
2
+ function t(r){if(r===null||typeof r!=="object")return!1;return"__archangel_error"in r&&typeof r.__archangel_error==="string"}function _(r){throw Error(r.__archangel_error,{cause:r.__archangel_error_trace??Error("Error trace only available in debug builds.")})}function e(r){if(t(r))_(r);return r}function o(r){let n=window[r];if(!n)console.warn(`Backend binding not available: ${r}`);return async(i)=>{if(!n)throw Error(`Backend binding not available: ${r}`);let a=await n(i);return e(a)}}var g=o("__plugin_process_run__"),s=(r,n)=>g({argv:r,...n?{cwd:n.cwd,env:n.env?Object.entries(n.env).map(([i,a])=>({key:i,value:a})):void 0}:{}});export{s as run};
3
+
4
+ //# debugId=1D349BCE5AF1D93464756E2164756E21
5
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1,11 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["..\\src\\internal\\binding.ts", "..\\src\\plugins\\process\\index.ts"],
4
+ "sourcesContent": [
5
+ "export interface BindingError {\n __archangel_error: string;\n __archangel_error_trace?: string;\n}\n\nexport function isBindingError(result: any): result is BindingError {\n if (result === null || typeof result !== \"object\") {\n return false;\n }\n\n return \"__archangel_error\" in result && typeof result.__archangel_error === \"string\";\n}\n\nexport function throwBindingError(error: BindingError): never {\n throw new Error(error.__archangel_error, {\n cause:\n error.__archangel_error_trace ?? new Error(\"Error trace only available in debug builds.\"),\n });\n}\n\nexport function handleBindingResult<T>(result: any): T {\n if (isBindingError(result)) {\n throwBindingError(result);\n }\n return result as T;\n}\n\ntype BindingFn<TArgs = any, TResult = any> = (args: TArgs) => Promise<TResult>;\n\nexport function createBinding<TArgs, TResult>(windowKey: string): BindingFn<TArgs, TResult> {\n const fn = (window as any)[windowKey];\n\n if (!fn) {\n console.warn(`Backend binding not available: ${windowKey}`);\n }\n\n return async (args: TArgs) => {\n if (!fn) {\n throw new Error(`Backend binding not available: ${windowKey}`);\n }\n\n const result = await fn(args);\n return handleBindingResult(result);\n };\n}\n",
6
+ "import { createBinding } from \"../../internal/binding\";\r\n\r\ntype EnvMapping = {\r\n key: string;\r\n value: string;\r\n};\r\n\r\ntype RunRequestBinding = {\r\n argv: string[];\r\n cwd?: string;\r\n env?: EnvMapping[];\r\n};\r\n\r\n\r\nexport type RunRequest = {\r\n cwd?: string;\r\n env?: Record<string, string>;\r\n};\r\n\r\nexport type RunResponse = {\r\n stdout: string;\r\n stderr: string;\r\n term: number;\r\n};\r\n\r\nconst runBinding = createBinding<RunRequestBinding, RunResponse>(\"__plugin_process_run__\");\r\n\r\n/**\r\n * Run a command\r\n * @param args - Object containing the command arguments, current working directory, and environment variables\r\n * @returns Promise resolving to the run response\r\n */\r\nexport const run = (argv: string[], req?: RunRequest) => runBinding({\r\n argv: argv,\r\n ...req ? {\r\n cwd: req.cwd,\r\n env: req.env ? Object.entries(req.env).map(([key, value]) => ({ key, value })) : undefined,\r\n } : {},\r\n});\r\n"
7
+ ],
8
+ "mappings": ";AAKO,SAAS,CAAc,CAAC,EAAqC,CAClE,GAAI,IAAW,MAAQ,OAAO,IAAW,SACvC,MAAO,GAGT,MAAO,sBAAuB,GAAU,OAAO,EAAO,oBAAsB,SAGvE,SAAS,CAAiB,CAAC,EAA4B,CAC5D,MAAU,MAAM,EAAM,kBAAmB,CACvC,MACE,EAAM,yBAA+B,MAAM,6CAA6C,CAC5F,CAAC,EAGI,SAAS,CAAsB,CAAC,EAAgB,CACrD,GAAI,EAAe,CAAM,EACvB,EAAkB,CAAM,EAE1B,OAAO,EAKF,SAAS,CAA6B,CAAC,EAA8C,CAC1F,IAAM,EAAM,OAAe,GAE3B,GAAI,CAAC,EACH,QAAQ,KAAK,kCAAkC,GAAW,EAG5D,MAAO,OAAO,IAAgB,CAC5B,GAAI,CAAC,EACH,MAAU,MAAM,kCAAkC,GAAW,EAG/D,IAAM,EAAS,MAAM,EAAG,CAAI,EAC5B,OAAO,EAAoB,CAAM,GCjBrC,IAAM,EAAa,EAA8C,wBAAwB,EAO5E,EAAM,CAAC,EAAgB,IAAqB,EAAW,CAClE,KAAM,KACH,EAAM,CACP,IAAK,EAAI,IACT,IAAK,EAAI,IAAM,OAAO,QAAQ,EAAI,GAAG,EAAE,IAAI,EAAE,EAAK,MAAY,CAAE,MAAK,OAAM,EAAE,EAAI,MACnF,EAAI,CAAC,CACP,CAAC",
9
+ "debugId": "1D349BCE5AF1D93464756E2164756E21",
10
+ "names": []
11
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@shahwali/archangel",
3
- "version": "0.0.3",
3
+ "version": "0.0.4",
4
4
  "files": [
5
5
  "dist"
6
6
  ],