aboutsummaryrefslogtreecommitdiff
path: root/src/fields/ScriptField.ts
diff options
context:
space:
mode:
authorbobzel <zzzman@gmail.com>2023-04-05 22:44:03 -0400
committerbobzel <zzzman@gmail.com>2023-04-05 22:44:03 -0400
commit9b41da1af16b982ee8ac2fc09f2f8b5d67eac9fb (patch)
treebc3f57cd5b31fd453d272c925f6d5b728ab63bae /src/fields/ScriptField.ts
parent9dae453967183b294bf4f7444b948023a1d52d39 (diff)
parent8f7e99641f84ad15f34ba9e4a60b664ac93d2e5d (diff)
Merge branch 'master' into data-visualization-view-naafi
Diffstat (limited to 'src/fields/ScriptField.ts')
-rw-r--r--src/fields/ScriptField.ts101
1 files changed, 51 insertions, 50 deletions
diff --git a/src/fields/ScriptField.ts b/src/fields/ScriptField.ts
index 68fb45987..2b8750714 100644
--- a/src/fields/ScriptField.ts
+++ b/src/fields/ScriptField.ts
@@ -6,11 +6,10 @@ import { scriptingGlobal, ScriptingGlobals } from '../client/util/ScriptingGloba
import { autoObject, Deserializable } from '../client/util/SerializationHelper';
import { numberRange } from '../Utils';
import { Doc, Field, Opt } from './Doc';
-import { Copy, Id, ToScriptString, ToString } from './FieldSymbols';
+import { Copy, Id, ToScriptString, ToString, ToValue } from './FieldSymbols';
import { List } from './List';
import { ObjectField } from './ObjectField';
-import { Cast, NumCast } from './Types';
-import { Plugins } from './util';
+import { Cast, StrCast } from './Types';
function optional(propSchema: PropSchema) {
return custom(
@@ -43,12 +42,11 @@ const scriptSchema = createSimpleSchema({
originalScript: true,
});
-function finalizeScript(script: ScriptField, captures: boolean) {
+function finalizeScript(script: ScriptField) {
const comp = CompileScript(script.script.originalScript, script.script.options);
if (!comp.compiled) {
throw new Error("Couldn't compile loaded script");
}
- !captures && ScriptField._scriptFieldCache.set(script.script.originalScript, comp);
if (script.setterscript) {
const compset = CompileScript(script.setterscript?.originalScript, script.setterscript.options);
if (!compset.compiled) {
@@ -72,9 +70,9 @@ async function deserializeScript(script: ScriptField) {
else if (!isNaN(Number(val))) captured[key] = Number(val);
else captured[key] = val;
})
- ).then(() => ((script as any).script = finalizeScript(script, true)));
+ ).then(() => ((script as any).script = finalizeScript(script)));
} else {
- (script as any).script = ScriptField.GetScriptFieldCache(script.script.originalScript) ?? finalizeScript(script, false);
+ (script as any).script = ScriptField.GetScriptFieldCache(script.script.originalScript) ?? finalizeScript(script);
}
}
@@ -105,30 +103,9 @@ export class ScriptField extends ObjectField {
}
this.rawscript = rawscript;
this.setterscript = setterscript;
- this.script = script ?? (CompileScript('false') as CompiledScript);
+ this.script = script ?? ScriptField.GetScriptFieldCache('false:') ?? (CompileScript('false', { addReturn: true }) as CompiledScript);
}
- // init(callback: (res: Field) => any) {
- // const options = this.options!;
- // const keys = Object.keys(options.options.capturedIds);
- // Server.GetFields(keys).then(fields => {
- // let captured: { [name: string]: Field } = {};
- // keys.forEach(key => captured[options.options.capturedIds[key]] = fields[key]);
- // const opts: ScriptOptions = {
- // addReturn: options.options.addReturn,
- // params: options.options.params,
- // requiredType: options.options.requiredType,
- // capturedVariables: captured
- // };
- // const script = CompileScript(options.script, opts);
- // if (!script.compiled) {
- // throw new Error("Can't compile script");
- // }
- // this._script = script;
- // callback(this);
- // });
- // }
-
[Copy](): ObjectField {
return new ScriptField(this.script, this.setterscript, this.rawscript);
}
@@ -137,13 +114,13 @@ export class ScriptField extends ObjectField {
}
[ToScriptString]() {
- return 'script field';
+ return this.script.originalScript;
}
[ToString]() {
return this.script.originalScript;
}
public static CompileScript(script: string, params: object = {}, addReturn = false, capturedVariables?: { [name: string]: Doc | string | number | boolean }) {
- const compiled = CompileScript(script, {
+ return CompileScript(script, {
params: {
this: Doc?.name || 'Doc', // this is the doc that executes the script
self: Doc?.name || 'Doc', // self is the root doc of the doc that executes the script
@@ -156,7 +133,6 @@ export class ScriptField extends ObjectField {
addReturn: addReturn,
capturedVariables,
});
- return compiled;
}
public static MakeFunction(script: string, params: object = {}, capturedVariables?: { [name: string]: Doc | string | number | boolean }) {
const compiled = ScriptField.CompileScript(script, params, true, capturedVariables);
@@ -175,30 +151,57 @@ export class ComputedField extends ScriptField {
_lastComputedResult: any;
//TODO maybe add an observable cache based on what is passed in for doc, considering there shouldn't really be that many possible values for doc
value = computedFn((doc: Doc) => this._valueOutsideReaction(doc));
- _valueOutsideReaction = (doc: Doc) => (this._lastComputedResult = this.script.run({ this: doc, self: Cast(doc.rootDocument, Doc, null) || doc, _last_: this._lastComputedResult, _readOnly_: true }, console.log).result);
+ _valueOutsideReaction = (doc: Doc) => (this._lastComputedResult = this.script.run({ this: doc, self: Cast(doc.rootDocument, Doc, null) ?? doc, value: '', _last_: this._lastComputedResult, _readOnly_: true }, console.log).result);
+ [ToValue](doc: Doc) {
+ return ComputedField.toValue(doc, this);
+ }
[Copy](): ObjectField {
return new ComputedField(this.script, this.setterscript, this.rawscript);
}
- public static MakeScript(script: string, params: object = {}) {
- const compiled = ScriptField.CompileScript(script, params, false);
- return compiled.compiled ? new ComputedField(compiled) : undefined;
- }
- public static MakeFunction(script: string, params: object = {}, capturedVariables?: { [name: string]: Doc | string | number | boolean }) {
- const compiled = ScriptField.CompileScript(script, params, true, capturedVariables);
- return compiled.compiled ? new ComputedField(compiled) : undefined;
+ public static MakeFunction(script: string, params: object = {}, capturedVariables?: { [name: string]: Doc | string | number | boolean }, setterscript?: string) {
+ const compiled = ScriptField.CompileScript(script, params, true, { value: '', ...capturedVariables });
+ const compiledsetter = setterscript ? ScriptField.CompileScript(setterscript, { ...params, value: 'any' }, false, capturedVariables) : undefined;
+ const compiledsetscript = compiledsetter?.compiled ? compiledsetter : undefined;
+ return compiled.compiled ? new ComputedField(compiled, compiledsetscript) : undefined;
}
- public static MakeInterpolated(fieldKey: string, interpolatorKey: string, doc: Doc, curTimecode: number) {
+ public static MakeInterpolatedNumber(fieldKey: string, interpolatorKey: string, doc: Doc, curTimecode: number, defaultVal: Opt<number>) {
if (!doc[`${fieldKey}-indexed`]) {
const flist = new List<number>(numberRange(curTimecode + 1).map(i => undefined) as any as number[]);
- flist[curTimecode] = NumCast(doc[fieldKey]);
+ flist[curTimecode] = Cast(doc[fieldKey], 'number', null);
+ doc[`${fieldKey}-indexed`] = flist;
+ }
+ const getField = ScriptField.CompileScript(`getIndexVal(self['${fieldKey}-indexed'], self.${interpolatorKey}, ${defaultVal})`, {}, true, {});
+ const setField = ScriptField.CompileScript(`setIndexVal(self['${fieldKey}-indexed'], self.${interpolatorKey}, value)`, { value: 'any' }, true, {});
+ return getField.compiled ? new ComputedField(getField, setField?.compiled ? setField : undefined) : undefined;
+ }
+ public static MakeInterpolatedString(fieldKey: string, interpolatorKey: string, doc: Doc, curTimecode: number) {
+ if (!doc[`${fieldKey}-indexed`]) {
+ const flist = new List<string>(numberRange(curTimecode + 1).map(i => undefined) as any as string[]);
+ flist[curTimecode] = StrCast(doc[fieldKey]);
doc[`${fieldKey}-indexed`] = flist;
}
const getField = ScriptField.CompileScript(`getIndexVal(self['${fieldKey}-indexed'], self.${interpolatorKey})`, {}, true, {});
const setField = ScriptField.CompileScript(`setIndexVal(self['${fieldKey}-indexed'], self.${interpolatorKey}, value)`, { value: 'any' }, true, {});
return getField.compiled ? new ComputedField(getField, setField?.compiled ? setField : undefined) : undefined;
}
+ public static MakeInterpolatedDataField(fieldKey: string, interpolatorKey: string, doc: Doc, curTimecode: number) {
+ if (doc[`${fieldKey}`] instanceof List) return;
+ if (!doc[`${fieldKey}-indexed`]) {
+ const flist = new List<Field>(numberRange(curTimecode + 1).map(i => undefined) as any as Field[]);
+ flist[curTimecode] = Field.Copy(doc[fieldKey]);
+ doc[`${fieldKey}-indexed`] = flist;
+ }
+ const getField = ScriptField.CompileScript(`getIndexVal(self['${fieldKey}-indexed'], self.${interpolatorKey})`, {}, true, {});
+ const setField = ScriptField.CompileScript(
+ `{setIndexVal (self['${fieldKey}-indexed'], self.${interpolatorKey}, value); console.log(self["${fieldKey}-indexed"][self.${interpolatorKey}],self.data,self["${fieldKey}-indexed"]))}`,
+ { value: 'any' },
+ false,
+ {}
+ );
+ return (doc[`${fieldKey}`] = getField.compiled ? new ComputedField(getField, setField?.compiled ? setField : undefined) : undefined);
+ }
}
export namespace ComputedField {
let useComputed = true;
@@ -221,12 +224,10 @@ export namespace ComputedField {
}
}
- export function initPlugin() {
- Plugins.addGetterPlugin((doc, _, value) => {
- if (useComputed && value instanceof ComputedField) {
- return { value: value._valueOutsideReaction(doc), shouldReturn: true };
- }
- });
+ export function toValue(doc: any, value: any) {
+ if (useComputed) {
+ return { value: value._valueOutsideReaction(doc) };
+ }
}
}
@@ -240,8 +241,8 @@ ScriptingGlobals.add(
);
ScriptingGlobals.add(
- function getIndexVal(list: any[], index: number) {
- return list?.reduce((p, x, i) => ((i <= index && x !== undefined) || p === undefined ? x : p), undefined as any);
+ function getIndexVal(list: any[], index: number, defaultVal: Opt<number> = undefined) {
+ return list?.reduce((p, x, i) => ((i <= index && x !== undefined) || p === undefined ? x : p), defaultVal);
},
'returns the value at a given index of a list',
'(list: any[], index: number)'