mirror of
				https://github.com/lightpanda-io/browser.git
				synced 2025-10-30 15:41:48 +00:00 
			
		
		
		
	dynamicImportCallback in JsContext
This commit is contained in:
		| @@ -196,203 +196,7 @@ pub fn Env(comptime State: type, comptime WebApis: type) type { | |||||||
|             errdefer isolate.deinit(); |             errdefer isolate.deinit(); | ||||||
|  |  | ||||||
|             // This is the callback that runs whenever a module is dynamically imported. |             // This is the callback that runs whenever a module is dynamically imported. | ||||||
|             isolate.setHostImportModuleDynamicallyCallback(struct { |             isolate.setHostImportModuleDynamicallyCallback(JsContext.dynamicModuleCallback); | ||||||
|                 pub fn callback( |  | ||||||
|                     v8_ctx: ?*const v8.c.Context, |  | ||||||
|                     host_defined_options: ?*const v8.c.Data, |  | ||||||
|                     resource_name: ?*const v8.c.Value, |  | ||||||
|                     v8_specifier: ?*const v8.c.String, |  | ||||||
|                     import_attrs: ?*const v8.c.FixedArray, |  | ||||||
|                 ) callconv(.c) ?*v8.c.Promise { |  | ||||||
|                     _ = host_defined_options; |  | ||||||
|                     _ = import_attrs; |  | ||||||
|                     const ctx: v8.Context = .{ .handle = v8_ctx.? }; |  | ||||||
|                     const context: *JsContext = @ptrFromInt(ctx.getEmbedderData(1).castTo(v8.BigInt).getUint64()); |  | ||||||
|                     const iso = context.isolate; |  | ||||||
|                     const resolver = v8.PromiseResolver.init(ctx); |  | ||||||
|  |  | ||||||
|                     const specifier: v8.String = .{ .handle = v8_specifier.? }; |  | ||||||
|                     const specifier_str = jsStringToZig(context.call_arena, specifier, iso) catch { |  | ||||||
|                         const error_msg = v8.String.initUtf8(iso, "Failed to parse module specifier"); |  | ||||||
|                         _ = resolver.reject(ctx, error_msg.toValue()); |  | ||||||
|                         return @constCast(resolver.getPromise().handle); |  | ||||||
|                     }; |  | ||||||
|                     const resource: v8.String = .{ .handle = resource_name.? }; |  | ||||||
|                     const resource_str = jsStringToZig(context.call_arena, resource, iso) catch { |  | ||||||
|                         const error_msg = v8.String.initUtf8(iso, "Failed to parse module resource"); |  | ||||||
|                         _ = resolver.reject(ctx, error_msg.toValue()); |  | ||||||
|                         return @constCast(resolver.getPromise().handle); |  | ||||||
|                     }; |  | ||||||
|  |  | ||||||
|                     const referrer_full_url = blk: { |  | ||||||
|                         // Search through module_identifier values to find matching resource |  | ||||||
|                         var it = context.module_identifier.valueIterator(); |  | ||||||
|                         while (it.next()) |full_url| { |  | ||||||
|                             // Extract just the filename from the full URL |  | ||||||
|                             const last_slash = std.mem.lastIndexOfScalar(u8, full_url.*, '/') orelse 0; |  | ||||||
|                             const filename = full_url.*[last_slash + 1 ..]; |  | ||||||
|  |  | ||||||
|                             // Compare with our resource string (removing ./ prefix if present) |  | ||||||
|                             const resource_clean = if (std.mem.startsWith(u8, resource_str, "./")) |  | ||||||
|                                 resource_str[2..] |  | ||||||
|                             else |  | ||||||
|                                 resource_str; |  | ||||||
|  |  | ||||||
|                             if (std.mem.eql(u8, filename, resource_clean)) { |  | ||||||
|                                 break :blk full_url.*; |  | ||||||
|                             } |  | ||||||
|                         } |  | ||||||
|  |  | ||||||
|                         // Fallback - maybe it's already a full URL in some cases? |  | ||||||
|                         break :blk resource_str; |  | ||||||
|                     }; |  | ||||||
|  |  | ||||||
|                     const normalized_specifier = @import("../url.zig").stitch( |  | ||||||
|                         context.context_arena, |  | ||||||
|                         specifier_str, |  | ||||||
|                         referrer_full_url, |  | ||||||
|                         .{ .alloc = .if_needed }, |  | ||||||
|                     ) catch unreachable; |  | ||||||
|  |  | ||||||
|                     // TODO: we need to resolve the full URL here and normalize it. |  | ||||||
|                     // That way we can pass the correct one in the module_loader. |  | ||||||
|  |  | ||||||
|                     log.info(.js, "dynamic import", .{ |  | ||||||
|                         .specifier = specifier_str, |  | ||||||
|                         .resource = resource_str, |  | ||||||
|                         .normalized = normalized_specifier, |  | ||||||
|                     }); |  | ||||||
|  |  | ||||||
|                     const module_loader = context.module_loader; |  | ||||||
|                     const source = module_loader.func(module_loader.ptr, normalized_specifier) catch { |  | ||||||
|                         const error_msg = v8.String.initUtf8(iso, "Failed to load module"); |  | ||||||
|                         _ = resolver.reject(ctx, error_msg.toValue()); |  | ||||||
|                         return @constCast(resolver.getPromise().handle); |  | ||||||
|                     } orelse { |  | ||||||
|                         const error_msg = v8.String.initUtf8(iso, "Module source not available"); |  | ||||||
|                         _ = resolver.reject(ctx, error_msg.toValue()); |  | ||||||
|                         return @constCast(resolver.getPromise().handle); |  | ||||||
|                     }; |  | ||||||
|  |  | ||||||
|                     var try_catch: TryCatch = undefined; |  | ||||||
|                     try_catch.init(context); |  | ||||||
|                     defer try_catch.deinit(); |  | ||||||
|  |  | ||||||
|                     const module = compileModule(iso, source, specifier_str) catch { |  | ||||||
|                         log.err(.js, "module compilation failed", .{ |  | ||||||
|                             .specifier = specifier_str, |  | ||||||
|                             .exception = try_catch.exception(context.call_arena) catch "unknown error", |  | ||||||
|                             .stack = try_catch.stack(context.call_arena) catch null, |  | ||||||
|                         }); |  | ||||||
|                         const error_msg = if (try_catch.hasCaught()) blk: { |  | ||||||
|                             const exception_str = try_catch.exception(context.call_arena) catch "Compilation error"; |  | ||||||
|                             break :blk v8.String.initUtf8(iso, exception_str orelse "Compilation error"); |  | ||||||
|                         } else v8.String.initUtf8(iso, "Module compilation failed"); |  | ||||||
|  |  | ||||||
|                         _ = resolver.reject(ctx, error_msg.toValue()); |  | ||||||
|                         return @constCast(resolver.getPromise().handle); |  | ||||||
|                     }; |  | ||||||
|  |  | ||||||
|                     context.module_identifier.putNoClobber(context.context_arena, module.getIdentityHash(), normalized_specifier) catch unreachable; |  | ||||||
|                     context.module_cache.putNoClobber(context.context_arena, normalized_specifier, v8.Persistent(v8.Module).init(iso, module)) catch unreachable; |  | ||||||
|  |  | ||||||
|                     const instantiated = module.instantiate(ctx, JsContext.resolveModuleCallback) catch { |  | ||||||
|                         log.err(.js, "module instantiation failed", .{ |  | ||||||
|                             .specifier = specifier_str, |  | ||||||
|                             .exception = try_catch.exception(context.call_arena) catch "unknown error", |  | ||||||
|                             .stack = try_catch.stack(context.call_arena) catch null, |  | ||||||
|                         }); |  | ||||||
|                         const error_msg = if (try_catch.hasCaught()) blk: { |  | ||||||
|                             const exception_str = try_catch.exception(context.call_arena) catch "Instantiation error"; |  | ||||||
|                             break :blk v8.String.initUtf8(iso, exception_str orelse "Instantiation error"); |  | ||||||
|                         } else v8.String.initUtf8(iso, "Module instantiation failed"); |  | ||||||
|  |  | ||||||
|                         _ = resolver.reject(ctx, error_msg.toValue()); |  | ||||||
|                         return @constCast(resolver.getPromise().handle); |  | ||||||
|                     }; |  | ||||||
|  |  | ||||||
|                     if (!instantiated) { |  | ||||||
|                         const error_msg = v8.String.initUtf8(iso, "Module did not instantiate"); |  | ||||||
|                         _ = resolver.reject(ctx, error_msg.toValue()); |  | ||||||
|                         return @constCast(resolver.getPromise().handle); |  | ||||||
|                     } |  | ||||||
|  |  | ||||||
|                     const evaluated = module.evaluate(ctx) catch { |  | ||||||
|                         log.err(.js, "module evaluation failed", .{ |  | ||||||
|                             .specifier = specifier_str, |  | ||||||
|                             .exception = try_catch.exception(context.call_arena) catch "unknown error", |  | ||||||
|                             .stack = try_catch.stack(context.call_arena) catch null, |  | ||||||
|                             .line = try_catch.sourceLineNumber() orelse 0, |  | ||||||
|                         }); |  | ||||||
|                         const error_msg = if (try_catch.hasCaught()) blk: { |  | ||||||
|                             const exception_str = try_catch.exception(context.call_arena) catch "Evaluation error"; |  | ||||||
|                             break :blk v8.String.initUtf8(iso, exception_str orelse "Evaluation error"); |  | ||||||
|                         } else v8.String.initUtf8(iso, "Module evaluation failed"); |  | ||||||
|  |  | ||||||
|                         _ = resolver.reject(ctx, error_msg.toValue()); |  | ||||||
|                         return @constCast(resolver.getPromise().handle); |  | ||||||
|                     }; |  | ||||||
|  |  | ||||||
|                     if (evaluated.isPromise()) { |  | ||||||
|                         const promise = v8.Promise{ .handle = evaluated.handle }; |  | ||||||
|  |  | ||||||
|                         const EvaluationData = struct { |  | ||||||
|                             module: v8.Persistent(v8.Module), |  | ||||||
|                             resolver: v8.Persistent(v8.PromiseResolver), |  | ||||||
|                         }; |  | ||||||
|  |  | ||||||
|                         const ev_data = context.context_arena.create(EvaluationData) catch unreachable; |  | ||||||
|                         ev_data.* = .{ |  | ||||||
|                             .module = v8.Persistent(v8.Module).init(iso, module), |  | ||||||
|                             .resolver = v8.Persistent(v8.PromiseResolver).init(iso, resolver), |  | ||||||
|                         }; |  | ||||||
|                         const external = v8.External.init(iso, @ptrCast(ev_data)); |  | ||||||
|  |  | ||||||
|                         const then_callback = v8.Function.initWithData(ctx, struct { |  | ||||||
|                             pub fn callback(info: ?*const v8.c.FunctionCallbackInfo) callconv(.c) void { |  | ||||||
|                                 const cb_info = v8.FunctionCallbackInfo{ .handle = info.? }; |  | ||||||
|                                 const cb_isolate = cb_info.getIsolate(); |  | ||||||
|                                 const cb_context = cb_isolate.getCurrentContext(); |  | ||||||
|                                 const data: *EvaluationData = @ptrCast(@alignCast(cb_info.getExternalValue())); |  | ||||||
|                                 const cb_module = data.module.castToModule(); |  | ||||||
|                                 const cb_resolver = data.resolver.castToPromiseResolver(); |  | ||||||
|  |  | ||||||
|                                 const namespace = cb_module.getModuleNamespace(); |  | ||||||
|                                 log.warn(.js, "module then promise", .{ |  | ||||||
|                                     .namespace = namespace, |  | ||||||
|                                 }); |  | ||||||
|                                 _ = cb_resolver.resolve(cb_context, namespace); |  | ||||||
|                             } |  | ||||||
|                         }.callback, external); |  | ||||||
|  |  | ||||||
|                         const catch_callback = v8.Function.initWithData(ctx, struct { |  | ||||||
|                             pub fn callback(info: ?*const v8.c.FunctionCallbackInfo) callconv(.c) void { |  | ||||||
|                                 log.warn(.js, "module catch promise", .{}); |  | ||||||
|                                 const cb_info = v8.FunctionCallbackInfo{ .handle = info.? }; |  | ||||||
|                                 const cb_context = cb_info.getIsolate().getCurrentContext(); |  | ||||||
|                                 const data: *EvaluationData = @ptrCast(@alignCast(cb_info.getExternalValue())); |  | ||||||
|                                 const cb_resolver = data.resolver.castToPromiseResolver(); |  | ||||||
|                                 _ = cb_resolver.reject(cb_context, cb_info.getData()); |  | ||||||
|                             } |  | ||||||
|                         }.callback, external); |  | ||||||
|  |  | ||||||
|                         _ = promise.thenAndCatch(ctx, then_callback, catch_callback) catch { |  | ||||||
|                             log.err(.js, "module evaluation is promise", .{ |  | ||||||
|                                 .specifier = specifier_str, |  | ||||||
|                                 .line = try_catch.sourceLineNumber() orelse 0, |  | ||||||
|                             }); |  | ||||||
|                             const error_msg = v8.String.initUtf8(iso, "Evaluation is a promise"); |  | ||||||
|                             _ = resolver.reject(ctx, error_msg.toValue()); |  | ||||||
|                             return @constCast(resolver.getPromise().handle); |  | ||||||
|                         }; |  | ||||||
|                     } else { |  | ||||||
|                         const namespace = module.getModuleNamespace(); |  | ||||||
|                         _ = resolver.resolve(ctx, namespace); |  | ||||||
|                     } |  | ||||||
|  |  | ||||||
|                     return @constCast(resolver.getPromise().handle); |  | ||||||
|                 } |  | ||||||
|             }.callback); |  | ||||||
|  |  | ||||||
|             isolate.enter(); |             isolate.enter(); | ||||||
|             errdefer isolate.exit(); |             errdefer isolate.exit(); | ||||||
| @@ -1706,6 +1510,214 @@ pub fn Env(comptime State: type, comptime WebApis: type) type { | |||||||
|                     type_index = prototype_index; |                     type_index = prototype_index; | ||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
|  |  | ||||||
|  |             pub fn dynamicModuleCallback( | ||||||
|  |                 v8_ctx: ?*const v8.c.Context, | ||||||
|  |                 host_defined_options: ?*const v8.c.Data, | ||||||
|  |                 resource_name: ?*const v8.c.Value, | ||||||
|  |                 v8_specifier: ?*const v8.c.String, | ||||||
|  |                 import_attrs: ?*const v8.c.FixedArray, | ||||||
|  |             ) callconv(.c) ?*v8.c.Promise { | ||||||
|  |                 _ = host_defined_options; | ||||||
|  |                 _ = import_attrs; | ||||||
|  |                 const ctx: v8.Context = .{ .handle = v8_ctx.? }; | ||||||
|  |                 const context: *JsContext = @ptrFromInt(ctx.getEmbedderData(1).castTo(v8.BigInt).getUint64()); | ||||||
|  |                 const iso = context.isolate; | ||||||
|  |                 const resolver = v8.PromiseResolver.init(context.v8_context); | ||||||
|  |  | ||||||
|  |                 const specifier: v8.String = .{ .handle = v8_specifier.? }; | ||||||
|  |                 const specifier_str = jsStringToZig(context.call_arena, specifier, iso) catch { | ||||||
|  |                     const error_msg = v8.String.initUtf8(iso, "Failed to parse module specifier"); | ||||||
|  |                     _ = resolver.reject(ctx, error_msg.toValue()); | ||||||
|  |                     return @constCast(resolver.getPromise().handle); | ||||||
|  |                 }; | ||||||
|  |                 const resource: v8.String = .{ .handle = resource_name.? }; | ||||||
|  |                 const resource_str = jsStringToZig(context.call_arena, resource, iso) catch { | ||||||
|  |                     const error_msg = v8.String.initUtf8(iso, "Failed to parse module resource"); | ||||||
|  |                     _ = resolver.reject(ctx, error_msg.toValue()); | ||||||
|  |                     return @constCast(resolver.getPromise().handle); | ||||||
|  |                 }; | ||||||
|  |  | ||||||
|  |                 const referrer_full_url = blk: { | ||||||
|  |                     var it = context.module_identifier.valueIterator(); | ||||||
|  |                     while (it.next()) |full_url| { | ||||||
|  |                         const last_slash = std.mem.lastIndexOfScalar(u8, full_url.*, '/') orelse 0; | ||||||
|  |                         const filename = full_url.*[last_slash + 1 ..]; | ||||||
|  |  | ||||||
|  |                         const resource_clean = if (std.mem.startsWith(u8, resource_str, "./")) | ||||||
|  |                             resource_str[2..] | ||||||
|  |                         else | ||||||
|  |                             resource_str; | ||||||
|  |  | ||||||
|  |                         if (std.mem.eql(u8, filename, resource_clean)) { | ||||||
|  |                             break :blk full_url.*; | ||||||
|  |                         } | ||||||
|  |                     } | ||||||
|  |  | ||||||
|  |                     break :blk resource_str; | ||||||
|  |                 }; | ||||||
|  |  | ||||||
|  |                 const normalized_specifier = @import("../url.zig").stitch( | ||||||
|  |                     context.context_arena, | ||||||
|  |                     specifier_str, | ||||||
|  |                     referrer_full_url, | ||||||
|  |                     .{ .alloc = .if_needed }, | ||||||
|  |                 ) catch unreachable; | ||||||
|  |  | ||||||
|  |                 _dynamicModuleCallback(context, resource_str, normalized_specifier, &resolver); | ||||||
|  |                 return @constCast(resolver.getPromise().handle); | ||||||
|  |             } | ||||||
|  |  | ||||||
|  |             fn _dynamicModuleCallback( | ||||||
|  |                 context: *JsContext, | ||||||
|  |                 resource: []const u8, | ||||||
|  |                 specifier: []const u8, | ||||||
|  |                 resolver: *const v8.PromiseResolver, | ||||||
|  |             ) void { | ||||||
|  |                 const iso = context.isolate; | ||||||
|  |                 const ctx = context.v8_context; | ||||||
|  |  | ||||||
|  |                 // Check module cache first. | ||||||
|  |                 if (context.module_cache.get(specifier)) |cached_module| { | ||||||
|  |                     const namespace = cached_module.castToModule().getModuleNamespace(); | ||||||
|  |                     _ = resolver.resolve(ctx, namespace); | ||||||
|  |                     return; | ||||||
|  |                 } | ||||||
|  |  | ||||||
|  |                 log.info(.js, "dynamic import", .{ | ||||||
|  |                     .specifier = specifier, | ||||||
|  |                     .resource = resource, | ||||||
|  |                     .normalized = specifier, | ||||||
|  |                 }); | ||||||
|  |  | ||||||
|  |                 const module_loader = context.module_loader; | ||||||
|  |                 const source = module_loader.func(module_loader.ptr, specifier) catch { | ||||||
|  |                     const error_msg = v8.String.initUtf8(iso, "Failed to load module"); | ||||||
|  |                     _ = resolver.reject(ctx, error_msg.toValue()); | ||||||
|  |                     return; | ||||||
|  |                 } orelse { | ||||||
|  |                     const error_msg = v8.String.initUtf8(iso, "Module source not available"); | ||||||
|  |                     _ = resolver.reject(ctx, error_msg.toValue()); | ||||||
|  |                     return; | ||||||
|  |                 }; | ||||||
|  |  | ||||||
|  |                 var try_catch: TryCatch = undefined; | ||||||
|  |                 try_catch.init(context); | ||||||
|  |                 defer try_catch.deinit(); | ||||||
|  |  | ||||||
|  |                 const new_module = compileModule(iso, source, specifier) catch { | ||||||
|  |                     log.err(.js, "module compilation failed", .{ | ||||||
|  |                         .specifier = specifier, | ||||||
|  |                         .exception = try_catch.exception(context.call_arena) catch "unknown error", | ||||||
|  |                         .stack = try_catch.stack(context.call_arena) catch null, | ||||||
|  |                     }); | ||||||
|  |                     const error_msg = if (try_catch.hasCaught()) blk: { | ||||||
|  |                         const exception_str = try_catch.exception(context.call_arena) catch "Compilation error"; | ||||||
|  |                         break :blk v8.String.initUtf8(iso, exception_str orelse "Compilation error"); | ||||||
|  |                     } else v8.String.initUtf8(iso, "Module compilation failed"); | ||||||
|  |  | ||||||
|  |                     _ = resolver.reject(ctx, error_msg.toValue()); | ||||||
|  |                     return; | ||||||
|  |                 }; | ||||||
|  |  | ||||||
|  |                 // Insert into Module Cache. | ||||||
|  |                 context.module_identifier.putNoClobber(context.context_arena, new_module.getIdentityHash(), specifier) catch unreachable; | ||||||
|  |                 context.module_cache.putNoClobber(context.context_arena, specifier, v8.Persistent(v8.Module).init(iso, new_module)) catch unreachable; | ||||||
|  |  | ||||||
|  |                 const instantiated = new_module.instantiate(ctx, JsContext.resolveModuleCallback) catch { | ||||||
|  |                     log.err(.js, "module instantiation failed", .{ | ||||||
|  |                         .specifier = specifier, | ||||||
|  |                         .exception = try_catch.exception(context.call_arena) catch "unknown error", | ||||||
|  |                         .stack = try_catch.stack(context.call_arena) catch null, | ||||||
|  |                     }); | ||||||
|  |                     const error_msg = if (try_catch.hasCaught()) blk: { | ||||||
|  |                         const exception_str = try_catch.exception(context.call_arena) catch "Instantiation error"; | ||||||
|  |                         break :blk v8.String.initUtf8(iso, exception_str orelse "Instantiation error"); | ||||||
|  |                     } else v8.String.initUtf8(iso, "Module instantiation failed"); | ||||||
|  |  | ||||||
|  |                     _ = resolver.reject(ctx, error_msg.toValue()); | ||||||
|  |                     return; | ||||||
|  |                 }; | ||||||
|  |  | ||||||
|  |                 if (!instantiated) { | ||||||
|  |                     const error_msg = v8.String.initUtf8(iso, "Module did not instantiate"); | ||||||
|  |                     _ = resolver.reject(ctx, error_msg.toValue()); | ||||||
|  |                     return; | ||||||
|  |                 } | ||||||
|  |  | ||||||
|  |                 const evaluated = new_module.evaluate(ctx) catch { | ||||||
|  |                     log.err(.js, "module evaluation failed", .{ | ||||||
|  |                         .specifier = specifier, | ||||||
|  |                         .exception = try_catch.exception(context.call_arena) catch "unknown error", | ||||||
|  |                         .stack = try_catch.stack(context.call_arena) catch null, | ||||||
|  |                         .line = try_catch.sourceLineNumber() orelse 0, | ||||||
|  |                     }); | ||||||
|  |                     const error_msg = if (try_catch.hasCaught()) blk: { | ||||||
|  |                         const exception_str = try_catch.exception(context.call_arena) catch "Evaluation error"; | ||||||
|  |                         break :blk v8.String.initUtf8(iso, exception_str orelse "Evaluation error"); | ||||||
|  |                     } else v8.String.initUtf8(iso, "Module evaluation failed"); | ||||||
|  |  | ||||||
|  |                     _ = resolver.reject(ctx, error_msg.toValue()); | ||||||
|  |                     return; | ||||||
|  |                 }; | ||||||
|  |  | ||||||
|  |                 if (evaluated.isPromise()) { | ||||||
|  |                     const promise = v8.Promise{ .handle = evaluated.handle }; | ||||||
|  |  | ||||||
|  |                     const EvaluationData = struct { | ||||||
|  |                         module: v8.Persistent(v8.Module), | ||||||
|  |                         resolver: v8.Persistent(v8.PromiseResolver), | ||||||
|  |                     }; | ||||||
|  |  | ||||||
|  |                     const ev_data = context.context_arena.create(EvaluationData) catch unreachable; | ||||||
|  |                     ev_data.* = .{ | ||||||
|  |                         .module = v8.Persistent(v8.Module).init(iso, new_module), | ||||||
|  |                         .resolver = v8.Persistent(v8.PromiseResolver).init(iso, resolver.*), | ||||||
|  |                     }; | ||||||
|  |                     const external = v8.External.init(iso, @ptrCast(ev_data)); | ||||||
|  |  | ||||||
|  |                     const then_callback = v8.Function.initWithData(ctx, struct { | ||||||
|  |                         pub fn callback(info: ?*const v8.c.FunctionCallbackInfo) callconv(.c) void { | ||||||
|  |                             const cb_info = v8.FunctionCallbackInfo{ .handle = info.? }; | ||||||
|  |                             const cb_isolate = cb_info.getIsolate(); | ||||||
|  |                             const cb_context = cb_isolate.getCurrentContext(); | ||||||
|  |                             const data: *EvaluationData = @ptrCast(@alignCast(cb_info.getExternalValue())); | ||||||
|  |                             const cb_module = data.module.castToModule(); | ||||||
|  |                             const cb_resolver = data.resolver.castToPromiseResolver(); | ||||||
|  |  | ||||||
|  |                             const namespace = cb_module.getModuleNamespace(); | ||||||
|  |                             log.warn(.js, "module then promise", .{ | ||||||
|  |                                 .namespace = namespace, | ||||||
|  |                             }); | ||||||
|  |                             _ = cb_resolver.resolve(cb_context, namespace); | ||||||
|  |                         } | ||||||
|  |                     }.callback, external); | ||||||
|  |  | ||||||
|  |                     const catch_callback = v8.Function.initWithData(ctx, struct { | ||||||
|  |                         pub fn callback(info: ?*const v8.c.FunctionCallbackInfo) callconv(.c) void { | ||||||
|  |                             log.warn(.js, "module catch promise", .{}); | ||||||
|  |                             const cb_info = v8.FunctionCallbackInfo{ .handle = info.? }; | ||||||
|  |                             const cb_context = cb_info.getIsolate().getCurrentContext(); | ||||||
|  |                             const data: *EvaluationData = @ptrCast(@alignCast(cb_info.getExternalValue())); | ||||||
|  |                             const cb_resolver = data.resolver.castToPromiseResolver(); | ||||||
|  |                             _ = cb_resolver.reject(cb_context, cb_info.getData()); | ||||||
|  |                         } | ||||||
|  |                     }.callback, external); | ||||||
|  |  | ||||||
|  |                     _ = promise.thenAndCatch(ctx, then_callback, catch_callback) catch { | ||||||
|  |                         log.err(.js, "module evaluation is promise", .{ | ||||||
|  |                             .specifier = specifier, | ||||||
|  |                             .line = try_catch.sourceLineNumber() orelse 0, | ||||||
|  |                         }); | ||||||
|  |                         const error_msg = v8.String.initUtf8(iso, "Evaluation is a promise"); | ||||||
|  |                         _ = resolver.reject(ctx, error_msg.toValue()); | ||||||
|  |                         return; | ||||||
|  |                     }; | ||||||
|  |                 } else { | ||||||
|  |                     const namespace = new_module.getModuleNamespace(); | ||||||
|  |                     _ = resolver.resolve(ctx, namespace); | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|         }; |         }; | ||||||
|  |  | ||||||
|         pub const Function = struct { |         pub const Function = struct { | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 Muki Kiboigo
					Muki Kiboigo