UNPKG

@awcrotwell/motion

Version:

Motion allows you to build reactive, real-time frontend UI components in your Amber application using pure Crystal that are reusable, testable & encapsulated. For brevity, we will call them MotionComponents.

72 lines (71 loc) 2.86 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); const dispatchEvent_1 = __importDefault(require("./dispatchEvent")); const serializeEvent_1 = __importDefault(require("./serializeEvent")); const reconcile_1 = __importDefault(require("./reconcile")); class Component { constructor(client, element) { this.client = client; this.element = element; this._beforeConnect(); this._subscription = this.client.consumer.subscriptions.create({ channel: `motion:${this.generateTopic()}`, // TODO: version: '0.2.0', state: this.element.getAttribute(this.client.stateAttribute), }, { connected: () => this._connect(), rejected: () => this._connectFailed(), disconnected: () => this._disconnect(), received: (newState) => this._render(newState), }); } processMotion(name, event = null) { if (!this._subscription) { this.client.log('Dropped motion', name, 'on', this.element); return; } this.client.log('Processing motion', name, 'on', this.element); const extraDataForEvent = event && this.client.getExtraDataForEvent(event); this._subscription.perform({ name, event: event && serializeEvent_1.default(event, extraDataForEvent), }); } shutdown() { this._subscription.unsubscribe(); delete this._subscription; this._disconnect(); } _beforeConnect() { this.client.log('Connecting component', this.element); dispatchEvent_1.default(this.element, 'motion:before-connect'); } _connect() { // debugger this.client.log('Component connected', this.element); dispatchEvent_1.default(this.element, 'motion:connect'); } _connectFailed() { this.client.log('Failed to connect component', this.element); dispatchEvent_1.default(this.element, 'motion:connect-failed'); } _disconnect() { this.client.log('Component disconnected', this.element); dispatchEvent_1.default(this.element, 'motion:disconnect'); } _render(newState) { dispatchEvent_1.default(this.element, 'motion:before-render'); reconcile_1.default(this.element, newState, this.client.keyAttribute); this.client.log('Component rendered', this.element); dispatchEvent_1.default(this.element, 'motion:render'); } // eslint-disable-next-line class-methods-use-this generateTopic() { return Math.random().toString(36).substring(2, 15) + Math.random().toString(36).substring(2, 15); } } exports.default = Component;