public BaristaModuleRecord(string name, JavaScriptValueSafeHandle moduleSpecifier, BaristaModuleRecord parentModule, IJavaScriptEngine engine, BaristaContext context, IBaristaModuleRecordFactory moduleRecordFactory, IBaristaModuleLoader moduleLoader, JavaScriptModuleRecord moduleRecord) : base(engine, moduleRecord) { m_name = name ?? throw new ArgumentNullException(nameof(name)); m_moduleSpecifier = moduleSpecifier ?? throw new ArgumentNullException(nameof(moduleSpecifier)); m_parentModule = parentModule; m_context = context ?? throw new ArgumentNullException(nameof(context)); m_moduleRecordFactory = moduleRecordFactory ?? throw new ArgumentNullException(nameof(moduleRecordFactory)); //Module loader is not required, but if not specified, imports will fail. m_moduleLoader = moduleLoader; //Associate functions that will handle module loading if (m_parentModule == null) { //Set the fetch module callback for the module. m_fetchImportedModuleCallbackHandle = InitFetchImportedModuleCallback(Handle); //Set the notify callback for the module. m_notifyCallbackHandle = InitNotifyModuleReadyCallback(Handle); } //Set the event that will be called prior to the engine collecting the context. JavaScriptObjectBeforeCollectCallback beforeCollectCallback = (IntPtr handle, IntPtr callbackState) => { OnBeforeCollect(handle, callbackState); }; m_beforeCollectCallbackDelegateHandle = GCHandle.Alloc(beforeCollectCallback); Engine.JsSetObjectBeforeCollectCallback(moduleRecord, IntPtr.Zero, beforeCollectCallback); }
private bool InstallModule(BaristaModuleRecord newModuleRecord, BaristaModuleRecord referencingModuleRecord, IBaristaModule module, JavaScriptValueSafeHandle specifier) { try { var moduleValue = module.ExportDefault(Context, referencingModuleRecord); return(CreateSingleValueModule(newModuleRecord, specifier, moduleValue)); } catch (Exception ex) { var error = Context.CreateError($"An error occurred while obtaining the default export of the native module named {newModuleRecord.Name}: {ex.Message}"); Engine.JsSetException(error.Handle); return(true); } }
private BaristaModuleRecord CreateBaristaModuleRecordInternal(BaristaContext context, string moduleName, JavaScriptValueSafeHandle specifier, BaristaModuleRecord parentModule = null, bool setAsHost = false, IBaristaModuleLoader moduleLoader = null) { JavaScriptModuleRecord moduleRecord = null; if (m_specifierModuleLookup.ContainsKey(specifier)) { moduleRecord = m_specifierModuleLookup[specifier]; } if (moduleRecord == null || moduleRecord.IsClosed || moduleRecord.IsInvalid) { if (m_specifierModuleLookup.ContainsKey(specifier)) { m_specifierModuleLookup.Remove(specifier); } moduleRecord = m_engine.JsInitializeModuleRecord(parentModule == null ? JavaScriptModuleRecord.Invalid : parentModule.Handle, specifier); } return(m_moduleReferencePool.GetOrAdd(moduleRecord, () => { //If a module loader hasn't be specified in the parameters, obtain one from DI. if (moduleLoader == null) { moduleLoader = m_serviceProvider.GetRequiredService <IBaristaModuleLoader>(); } var module = new BaristaModuleRecord(moduleName.ToString(), specifier, parentModule, m_engine, context, this, moduleLoader, moduleRecord); m_specifierModuleLookup.Add(specifier, moduleRecord); //If specified, indicate as host module. if (setAsHost == true) { m_engine.JsSetModuleHostInfo(moduleRecord, JavaScriptModuleHostInfoKind.HostDefined, specifier.DangerousGetHandle()); } void beforeCollect(object sender, BaristaObjectBeforeCollectEventArgs args) { context.BeforeCollect -= beforeCollect; m_moduleReferencePool.RemoveHandle(new JavaScriptModuleRecord(args.Handle)); if (sender is BaristaModuleRecord baristaModuleRecord) { m_specifierModuleLookup.Remove(baristaModuleRecord.Specifier); } } module.BeforeCollect += beforeCollect; return module; })); }
/// <summary> /// Creates a module that returns the specified value. /// </summary> /// <param name="valueSafeHandle"></param> /// <param name="referencingModuleRecord"></param> /// <param name="specifierHandle"></param> /// <param name="dependentModuleRecord"></param> /// <returns></returns> private bool CreateSingleValueModule(BaristaModuleRecord moduleRecord, JavaScriptValueSafeHandle specifier, JsValue defaultExportedValue) { var globalId = Guid.NewGuid(); var exportSymbol = Context.Symbol.For($"$DEFAULTEXPORT_{globalId.ToString()}"); var exposeNativeValueScript = $@" const defaultExport = global[Symbol.for('$DEFAULTEXPORT_{globalId.ToString()}')]; export default defaultExport; "; Context.Object.DefineProperty(Context.GlobalObject, exportSymbol, new JsPropertyDescriptor() { Configurable = false, Enumerable = false, Writable = false, Value = defaultExportedValue }); moduleRecord.ParseModuleSource(exposeNativeValueScript); return(false); }
public BaristaModuleRecord CreateBaristaModuleRecord(BaristaContext context, JavaScriptValueSafeHandle specifier, BaristaModuleRecord parentModule = null, bool setAsHost = false, IBaristaModuleLoader moduleLoader = null) { if (context == null) { throw new ArgumentNullException(nameof(context)); } if (specifier == null || specifier.IsClosed || specifier.IsInvalid) { throw new ArgumentNullException(nameof(specifier)); } var moduleNameValue = context.CreateValue <JsString>(specifier); if (moduleNameValue == null) { throw new InvalidOperationException("Specifier is expected to be a string value."); } return(CreateBaristaModuleRecordInternal(context, moduleNameValue.ToString(), specifier, parentModule, setAsHost, moduleLoader)); }
public BaristaModuleRecord CreateBaristaModuleRecord(BaristaContext context, string moduleName, BaristaModuleRecord parentModule = null, bool setAsHost = false, IBaristaModuleLoader moduleLoader = null) { if (context == null) { throw new ArgumentNullException(nameof(context)); } var moduleNameValue = context.CreateString(moduleName); return(CreateBaristaModuleRecordInternal(context, moduleName, moduleNameValue.Handle, parentModule, setAsHost, moduleLoader)); }