Example #1
0
        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);
        }
Example #2
0
 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;
            }));
        }
Example #4
0
        /// <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));
        }