diff options
author | Tyler Schicke <tyler_schicke@brown.edu> | 2019-06-27 12:03:23 -0400 |
---|---|---|
committer | Tyler Schicke <tyler_schicke@brown.edu> | 2019-06-27 12:03:23 -0400 |
commit | 185b888f6fb4dae3f814350bbab8030e0ed7c135 (patch) | |
tree | 7292d7f4b65425dee3328bb95ec45fb46b86e8d2 /src/new_fields/ScriptField.ts | |
parent | 78261779207a273a7bd9ef35d66b4e787d2bf96f (diff) | |
parent | cb9a1b6419bd0932ad05bd517efa4be668682540 (diff) |
Merge branch 'master' of github-tsch-brown:browngraphicslab/Dash-Web into text_box_ab
Diffstat (limited to 'src/new_fields/ScriptField.ts')
-rw-r--r-- | src/new_fields/ScriptField.ts | 94 |
1 files changed, 94 insertions, 0 deletions
diff --git a/src/new_fields/ScriptField.ts b/src/new_fields/ScriptField.ts new file mode 100644 index 000000000..3d56e9374 --- /dev/null +++ b/src/new_fields/ScriptField.ts @@ -0,0 +1,94 @@ +import { ObjectField } from "./ObjectField"; +import { CompiledScript, CompileScript } from "../client/util/Scripting"; +import { Copy, ToScriptString, Parent, SelfProxy } from "./FieldSymbols"; +import { serializable, createSimpleSchema, map, primitive, object, deserialize, PropSchema, custom, SKIP } from "serializr"; +import { Deserializable } from "../client/util/SerializationHelper"; +import { Doc } from "../new_fields/Doc"; + +function optional(propSchema: PropSchema) { + return custom(value => { + if (value !== undefined) { + return propSchema.serializer(value); + } + return SKIP; + }, (jsonValue: any, context: any, oldValue: any, callback: (err: any, result: any) => void) => { + if (jsonValue !== undefined) { + return propSchema.deserializer(jsonValue, callback, context, oldValue); + } + return SKIP; + }); +} + +const optionsSchema = createSimpleSchema({ + requiredType: true, + addReturn: true, + typecheck: true, + readonly: true, + params: optional(map(primitive())) +}); + +const scriptSchema = createSimpleSchema({ + options: object(optionsSchema), + originalScript: true +}); + +function deserializeScript(script: ScriptField) { + const comp = CompileScript(script.script.originalScript, script.script.options); + if (!comp.compiled) { + throw new Error("Couldn't compile loaded script"); + } + (script as any).script = comp; +} + +@Deserializable("script", deserializeScript) +export class ScriptField extends ObjectField { + @serializable(object(scriptSchema)) + readonly script: CompiledScript; + + constructor(script: CompiledScript) { + super(); + + this.script = script; + } + + // 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); + } + + [ToScriptString]() { + return "script field"; + } +} + +@Deserializable("computed", deserializeScript) +export class ComputedField extends ScriptField { + //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(doc: Doc) { + const val = this.script.run({ this: doc }); + if (val.success) { + return val.result; + } + return undefined; + } +}
\ No newline at end of file |