UNPKG

chai-latte

Version:

Build expressive & readable fluent interface libraries.

127 lines 3.91 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.Expression = exports.register = void 0; const ConfigurableCallback_1 = require("./lib/ConfigurableCallback"); ; const register = (...args) => { const callback = args.pop(); return args.map((createUsePattern) => { const expression = new Expression(callback); const buildListener = expression.createBuilderProxy(); createUsePattern(buildListener); const api = expression.getFluentAPI(); return { api, callback, expression, }; }); }; exports.register = register; class Expression { fluentAPI = {}; pointer; static callbacks = new WeakSet(); callbacks = new Set(); callback; args = []; constructor(callback) { this.callback = callback; Expression.callbacks.add(callback); this.pointer = new BuildPointer(this.fluentAPI); } index = 0; setExpressionIdx(index) { this.index = index; this.callbacks.forEach((callback) => { }); } static isFinalCallback(cb) { return Expression.callbacks.has(cb); } getFluentAPI() { return this.fluentAPI; } createConfigurableCallback() { const callback = new ConfigurableCallback_1.ConfigurableCallback(this); this.callbacks.add(callback); return callback; } isLastPointerCallback() { const lastPointer = this.pointer.getLastPointer(); const isLastPointerCallback = typeof lastPointer === 'function'; return isLastPointerCallback; } debugId = ''; updateDebugProp(prop) { this.debugId += this.debugId ? '.' + prop : prop; } updateDebugFunction(arg) { if (typeof arg === 'undefined') { this.debugId += '()'; return; } this.debugId += '(' + arg.name + ')'; } callbackCount = 0; handleFunctionCalled(arg) { const fluentFunction = this.createConfigurableCallback(); this.pointer.overrideLastPointer(fluentFunction.callback); fluentFunction.updateArg(arg); fluentFunction.setCallIdx(this.callbackCount++); this.updateDebugFunction(arg); } handlePropertyAccess(prop) { const isAccessingPropAfterCall = this.isLastPointerCallback(); if (isAccessingPropAfterCall) { const lastPointer = this.pointer.getLastPointer(); const fluentFunction = ConfigurableCallback_1.ConfigurableCallback.getBuilderOf(lastPointer); const nextReturn = {}; this.pointer = new BuildPointer(nextReturn); fluentFunction.updateReturn(nextReturn); } this.updateDebugProp(prop); this.pointer.accessProp(prop); this.pointer.movePointer(prop); } createBuilderProxy() { const attribute = (arg) => { this.handleFunctionCalled(arg); return proxyBuilder; }; const proxyBuilder = new Proxy(attribute, { get: (target, prop) => { this.handlePropertyAccess(prop); return proxyBuilder; }, }); return proxyBuilder; } } exports.Expression = Expression; class BuildPointer { lastWord = null; lastPointer = null; pointer = null; constructor(initialValue) { this.pointer = initialValue; } overrideLastPointer(override) { return this.lastPointer[this.lastWord] = override; ; } getLastPointer() { return this.lastPointer?.[this.lastWord]; } movePointer(prop) { this.lastPointer = this.pointer; this.lastWord = prop; this.pointer = this.pointer[prop]; } accessProp(prop) { if (!this.pointer[prop]) { this.pointer[prop] = {}; } } } //# sourceMappingURL=register.js.map