nrgy
Version:
The library for reactive programming using efficient computing and MVC/MVVM patterns
291 lines (271 loc) • 8.48 kB
JavaScript
;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;