Skip to content

Commit

Permalink
refactor(model): convert to ts
Browse files Browse the repository at this point in the history
not complete, but all models are know ts based
  • Loading branch information
marcalexiei committed Jul 10, 2020
1 parent 0877e02 commit b0ad348
Show file tree
Hide file tree
Showing 24 changed files with 556 additions and 262 deletions.
6 changes: 5 additions & 1 deletion .eslintrc.json
Expand Up @@ -95,11 +95,15 @@
"no-useless-escape": 0,
"no-console": "error",
"no-dupe-class-members": "off",

"@typescript-eslint/no-use-before-define": "off",
"@typescript-eslint/no-empty-function": ["error", {
"allow": ["methods"]
}],
"@typescript-eslint/no-unused-vars": "error"
"@typescript-eslint/no-unused-vars": "error",
"@typescript-eslint/explicit-function-return-type": ["warn", {
"allowExpressions": true
}]
},
"overrides": [{
// disable typescript rules for JS files
Expand Down
@@ -1,17 +1,32 @@
import { Computation as ComputationType, ComputationDescriptor } from 'types/Computation';
import { Keypath } from 'types/Keypath';
import bind from 'utils/bind';
import { isFunction, isString, isObjectType } from 'utils/is';
import { fatal } from 'utils/log';

import { createFunctionFromString } from '../config/runtime-parser';

export default function getComputationSignature(ractive, key, signature) {
export interface ComputationSignature {
// TODO add ractive type on this param
getter: (this: any, context: any, keypath: Keypath) => any;
setter: (value: any, context: any, keypath: Keypath) => void;
getterString: string;
setterString: string;
getterUseStack: boolean;
}

export default function getComputationSignature(
ractive, // TODO add ractive type
key: string,
signature: ComputationType<any> // TODO add ractive type
): ComputationSignature {
let getter;
let setter;

// useful for debugging
let getterString;
let getterUseStack;
let setterString;
let getterString: string;
let getterUseStack: boolean;
let setterString: string;

if (isFunction(signature)) {
getter = bind(signature, ractive);
Expand All @@ -24,7 +39,8 @@ export default function getComputationSignature(ractive, key, signature) {
getterString = signature;
}

if (isObjectType(signature)) {
// TODO add ractive type
if (isObjectType<ComputationDescriptor<any>>(signature)) {
if (isString(signature.get)) {
getter = createFunctionFromString(signature.get, ractive);
getterString = signature.get;
Expand Down
11 changes: 6 additions & 5 deletions src/global/capture.ts
Expand Up @@ -2,22 +2,23 @@ import ModelBase from 'model/ModelBase';
import KeyModel from 'model/specials/KeyModel';
import { addToArray } from 'utils/array';

// TODO refine types on this two variables and in stopCapturing function
const stack = [];
let captureGroup: CapturableModel[];

type CapturableModel = ModelBase | KeyModel;
let captureGroup: [];

export function startCapturing(): void {
stack.push((captureGroup = []));
}

export function capture(model: CapturableModel): void {
export function capture(model: KeyModel): void;
export function capture(model: ModelBase): void;
export function capture(model: ModelBase | KeyModel): void {
if (captureGroup) {
addToArray(captureGroup, model);
}
}

export function stopCapturing(): CapturableModel[] {
export function stopCapturing(): any[] {
const dependencies = stack.pop();
captureGroup = stack[stack.length - 1];
return dependencies;
Expand Down
40 changes: 23 additions & 17 deletions src/model/Computation.js → src/model/Computation.ts
@@ -1,17 +1,22 @@
/* eslint no-console:"off" */

import { hasConsole } from 'config/environment';
import { capture, startCapturing, stopCapturing } from 'src/global/capture';
import runloop from 'src/global/runloop';
import { ComputationSignature } from 'src/Ractive/helpers/getComputationSignature';
import { isEqual } from 'utils/is';
import { warnIfDebug } from 'utils/log';

import ComputationChild from './ComputationChild';
import Model, { shared } from './Model';
import { maybeBind, noVirtual } from './ModelBase';
import { maybeBind, noVirtual, ModelDependency, ModelGetOpts } from './ModelBase';

export default class Computation extends Model implements ModelDependency {
public signature: ComputationSignature;
public dependencies: Model[];
public pattern: RegExp;

export default class Computation extends Model {
constructor(parent, signature, key) {
private dirty: boolean;

constructor(parent: Model, signature: ComputationSignature, key: string) {
super(parent, key);

this.signature = signature;
Expand All @@ -21,11 +26,6 @@ export default class Computation extends Model {

this.dependencies = [];

this.children = [];
this.childByKey = {};

this.deps = [];

this.dirty = true;

// TODO: is there a less hackish way to do this?
Expand All @@ -37,7 +37,7 @@ export default class Computation extends Model {
return undefined;
}

get(shouldCapture, opts) {
get(shouldCapture?: boolean, opts?: ModelGetOpts) {
if (shouldCapture) capture(this);

if (this.dirty) {
Expand Down Expand Up @@ -80,6 +80,7 @@ export default class Computation extends Model {
} catch (err) {
warnIfDebug(`Failed to compute ${this.getKeypath()}: ${err.message || err}`);

/* eslint-disable no-console */
// TODO this is all well and good in Chrome, but...
// ...also, should encapsulate this stuff better, and only
// show it if Ractive.DEBUG
Expand All @@ -97,6 +98,7 @@ export default class Computation extends Model {
);
if (console.groupCollapsed) console.groupEnd();
}
/* eslint-enable no-console */
}

const dependencies = stopCapturing();
Expand All @@ -106,16 +108,16 @@ export default class Computation extends Model {
return result;
}

mark() {
mark(): void {
this.handleChange();
}

rebind(next, previous) {
rebind(next, previous): void {
// computations will grab all of their deps again automagically
if (next !== previous) this.handleChange();
}

set(value) {
set(value): void {
if (this.isReadonly) {
throw new Error(`Cannot set read-only computed value '${this.key}'`);
}
Expand All @@ -124,7 +126,7 @@ export default class Computation extends Model {
this.mark();
}

setDependencies(dependencies) {
setDependencies(dependencies: Model[]): void {
// unregister any soft dependencies we no longer have
let i = this.dependencies.length;
while (i--) {
Expand All @@ -142,7 +144,9 @@ export default class Computation extends Model {
this.dependencies = dependencies;
}

teardown() {
handleChange(): void {}

teardown(): void {
let i = this.dependencies.length;
while (i--) {
if (this.dependencies[i]) this.dependencies[i].unregister(this);
Expand All @@ -155,6 +159,8 @@ export default class Computation extends Model {
const prototype = Computation.prototype;
const child = ComputationChild.prototype;
prototype.handleChange = child.handleChange;
prototype.joinKey = child.joinKey;

// function signature do not match return types so use any
prototype.joinKey = child.joinKey as any;

shared.Computation = Computation;
19 changes: 12 additions & 7 deletions src/model/ComputationChild.js → src/model/ComputationChild.ts
Expand Up @@ -4,9 +4,14 @@ import { isUndefined } from 'utils/is';
import { hasOwn } from 'utils/object';

import Model from './Model';
import { ModelGetOpts } from './ModelBase';

export default class ComputationChild extends Model {
constructor(parent, key) {
public parent;

private dirty: boolean;

constructor(parent, key: string) {
super(parent, key);

this.isReadonly = !this.root.ractive.syncComputedChildren;
Expand All @@ -18,13 +23,13 @@ export default class ComputationChild extends Model {
return this.parent.setRoot;
}

applyValue(value) {
applyValue(value): void {
super.applyValue(value);

if (!this.isReadonly) {
let source = this.parent;
let source: any = this.parent;
// computed models don't have a shuffle method
while (source && source.shuffle) {
while (source?.shuffle) {
source = source.parent;
}

Expand All @@ -38,7 +43,7 @@ export default class ComputationChild extends Model {
}
}

get(shouldCapture, opts) {
get(shouldCapture?: boolean, opts?: ModelGetOpts) {
if (shouldCapture) capture(this);

if (this.dirty) {
Expand All @@ -54,7 +59,7 @@ export default class ComputationChild extends Model {
: this.value;
}

handleChange() {
handleChange(): void {
if (this.dirty) return;
this.dirty = true;

Expand All @@ -65,7 +70,7 @@ export default class ComputationChild extends Model {
this.children.forEach(handleChange);
}

joinKey(key) {
joinKey(key: string): this {
if (isUndefined(key) || key === '') return this;

if (!hasOwn(this.childByKey, key)) {
Expand Down

0 comments on commit b0ad348

Please sign in to comment.