UNPKG

nrgy

Version:

The library for reactive programming using efficient computing and MVC/MVVM patterns

291 lines (271 loc) 8.48 kB
"use strict";Object.defineProperty(exports, "__esModule", {value: true}); var _chunkDUWWIS26cjs = require('./chunk-DUWWIS26.cjs'); var _chunk4OYRW4HCcjs = require('./chunk-4OYRW4HC.cjs'); // src/mvc/controller.ts var ControllerConstructorError = class extends Error { constructor(message) { super(message); this.name = "ControllerConstructorError"; } }; var BaseController = class { constructor(paramsOrProviders, extensions) { this.onCreateSignal = _chunk4OYRW4HCcjs.signal.call(void 0, { sync: false }); this.onDestroySignal = _chunk4OYRW4HCcjs.signal.call(void 0, { sync: true }); this.context = createControllerContext(paramsOrProviders, extensions); this.scope = this.context.scope; this.params = this.context.params; this.scope.effect(this.onCreateSignal, () => this.onCreated()); this.scope.effect(this.onDestroySignal, () => this.onDestroy()); this.onCreateSignal(); } /** * Called when the controller is created. * * This callback is called in a next microtask as soon as the controller is created. */ onCreated() { } /** * Called when the controller is destroyed synchronously. */ onDestroy() { } /** * Destroys the controller */ destroy() { this.onDestroySignal(); this.scope.destroy(); } }; var ControllerDeclarationBuilder = class { /** * Creates a new builder * * @param extensions Extensions that should be applied to the controller */ constructor(extensions = []) { this.extensions = extensions; } /** * Declares the controller with the given parameters */ params() { return this; } /** * Declares the controller with the given extension */ extend(extension) { this.extensions.push(extension); return this; } /** * Creates the controller declaration using declared context and the given factory */ apply(factory) { return createControllerDeclaration( factory, this.extensions ); } /** * Returns the base class for the controller using the declared context */ getBaseClass() { const extensions = this.extensions; return class extends BaseController { constructor(paramsOrProviders) { super(paramsOrProviders, extensions); } }; } }; function declareController(factory) { const builder = new ControllerDeclarationBuilder(); return factory ? builder.apply(factory) : builder; } function createControllerDeclaration(factory, extensions) { function constructorFn(paramsOrProviders) { return controllerConstructor( factory, paramsOrProviders, extensions ); } return constructorFn; } function controllerConstructor(factory, paramsOrProviders, extensions) { var _a; const context = createControllerContext(paramsOrProviders, extensions); const scope = context.scope; const controller = (_a = factory(context)) != null ? _a : { destroy: void 0 }; const originalDestroy = controller.destroy; if (originalDestroy) { scope.onDestroy(() => originalDestroy.call(controller)); } return Object.assign(controller, { destroy: () => scope.destroy() }); } function resolveParamsAndProviders(paramsOrProviders) { return Array.isArray(paramsOrProviders) ? { params: void 0, providers: paramsOrProviders } : { params: paramsOrProviders, providers: [] }; } function createControllerContext(paramsOrProviders, extensions) { var _a, _b; const scope = _chunkDUWWIS26cjs.createScope.call(void 0, ); const args = resolveParamsAndProviders(paramsOrProviders); const extensionParams = args.providers.length > 0 ? createExtensionParams(args.providers) : void 0; const params = (_b = (_a = args.params) != null ? _a : extensionParams == null ? void 0 : extensionParams.controllerParams) != null ? _b : {}; const baseContext = { scope, params }; const context = extensions ? extensions.reduce( (prevContext, extension) => extension(prevContext, extensionParams), baseContext ) : baseContext; const factoryContext = { ...context, create(declaration, params2) { const nextProviders = [ ...args.providers, provideControllerParams(params2) ]; const controller = new declaration(nextProviders); return scope.add(controller); } }; return factoryContext; } function createExtensionParams(providers) { return providers.reduce((params, provider) => provider(params), {}); } function provideControllerParams(params) { return function(extensionParams) { extensionParams["controllerParams"] = params; return extensionParams; }; } function provideExtensionParams(params) { return function(extensionParams) { return { ...extensionParams, ...params }; }; } // src/mvc/withView.ts var NRGY_EXTENSION_VIEW_KEY = "nrgy.view"; function withView() { return (sourceContext, extensionParams) => { const view = extensionParams == null ? void 0 : extensionParams[NRGY_EXTENSION_VIEW_KEY]; if (!view) { throw new ControllerConstructorError("View is not provided"); } return { ...sourceContext, view }; }; } function provideView(view) { return (params) => { params[NRGY_EXTENSION_VIEW_KEY] = view; return params; }; } // src/mvc/viewModel.ts var BaseViewController = class extends BaseController { constructor(paramsOrProviders, extensions) { super(paramsOrProviders, extensions); this.view = this.context.view; this.props = this.context.view.props; } }; var ViewModelDeclarationBuilder = class { constructor(extensions = []) { this.extensions = extensions; } extend(extension) { this.extensions.push(extension); return this; } apply(factory) { const extensions = [...this.extensions, withView()]; const result = createControllerDeclaration((context) => { const partialViewModel = factory(context); return Object.assign(partialViewModel, { props: context.view.props }); }, extensions); return result; } getBaseClass() { const extensions = [...this.extensions, withView()]; class BaseClass extends BaseViewController { constructor(paramsOrProviders) { super(paramsOrProviders, extensions); } } return BaseClass; } }; function declareViewModel(factory) { const builder = new ViewModelDeclarationBuilder(); return factory ? builder.apply(factory) : builder; } // src/mvc/view.ts var ViewStatuses = { unmounted: "unmounted", mounted: "mounted", destroyed: "destroyed" }; // src/mvc/viewProxy.ts function createViewProxy(initialProps) { const status = _chunk4OYRW4HCcjs.atom.call(void 0, ViewStatuses.unmounted); const props = {}; const readonlyProps = {}; const scope = _chunkDUWWIS26cjs.createScope.call(void 0, ); if (initialProps) { Object.keys(initialProps).forEach((key) => { const store = scope.atom(initialProps[key]); props[key] = store; readonlyProps[key] = store.asReadonly(); }); } const onMount = _chunk4OYRW4HCcjs.signal.call(void 0, { sync: true }); const onUpdate = _chunk4OYRW4HCcjs.signal.call(void 0, { sync: true }); const onUnmount = _chunk4OYRW4HCcjs.signal.call(void 0, { sync: true }); return { status: status.asReadonly(), props: readonlyProps, onMount, onUpdate, onUnmount, mount() { if (status() === ViewStatuses.unmounted) { status.set(ViewStatuses.mounted); onMount(); } }, update(nextProps) { if (status() !== ViewStatuses.mounted) { return; } if (nextProps) { Object.keys(nextProps).forEach((key) => { var _a; (_a = props[key]) == null ? void 0 : _a.set(nextProps[key]); }); } onUpdate(nextProps != null ? nextProps : {}); }, unmount() { if (status() === ViewStatuses.mounted) { status.set(ViewStatuses.unmounted); onUnmount(); } }, destroy() { if (status() !== ViewStatuses.destroyed) { onUnmount(); status.set(ViewStatuses.destroyed); scope.destroy(); } } }; } exports.ControllerConstructorError = ControllerConstructorError; exports.declareController = declareController; exports.provideControllerParams = provideControllerParams; exports.provideExtensionParams = provideExtensionParams; exports.withView = withView; exports.provideView = provideView; exports.declareViewModel = declareViewModel; exports.createViewProxy = createViewProxy;