aboutsummaryrefslogtreecommitdiff
path: root/src/fields/ScriptField.ts
diff options
context:
space:
mode:
authormehekj <mehek.jethani@gmail.com>2022-03-17 17:08:25 -0400
committermehekj <mehek.jethani@gmail.com>2022-03-17 17:08:25 -0400
commit1f7cf7babc76ecff5aef5fe663c48e067e85dd26 (patch)
treeadab9947ee887b57f2ff630a78139853b2011f92 /src/fields/ScriptField.ts
parent1e3ad4de06f83eab54628de660529fefb9a0dc63 (diff)
parent73ba1a0395167ab5949f71d0c82fa7188d37ab5c (diff)
Merge remote-tracking branch 'origin/speedups2' into temporalmedia-mehek
Diffstat (limited to 'src/fields/ScriptField.ts')
-rw-r--r--src/fields/ScriptField.ts91
1 files changed, 38 insertions, 53 deletions
diff --git a/src/fields/ScriptField.ts b/src/fields/ScriptField.ts
index bd93bf5fb..40ca0ce22 100644
--- a/src/fields/ScriptField.ts
+++ b/src/fields/ScriptField.ts
@@ -1,15 +1,16 @@
-import { ObjectField } from "./ObjectField";
-import { CompiledScript, CompileScript, scriptingGlobal, ScriptOptions, CompileError, CompileResult, Scripting } from "../client/util/Scripting";
-import { Copy, ToScriptString, ToString, Parent, SelfProxy } from "./FieldSymbols";
-import { serializable, createSimpleSchema, map, primitive, object, deserialize, PropSchema, custom, SKIP } from "serializr";
-import { Deserializable, autoObject } from "../client/util/SerializationHelper";
-import { Doc, Field, Opt } from "./Doc";
-import { Plugins, setter } from "./util";
import { computedFn } from "mobx-utils";
+import { createSimpleSchema, custom, map, object, primitive, PropSchema, serializable, SKIP } from "serializr";
+import { CompiledScript, CompileScript } from "../client/util/Scripting";
+import { scriptingGlobal, ScriptingGlobals } from "../client/util/ScriptingGlobals";
+import { autoObject, Deserializable } from "../client/util/SerializationHelper";
+import { numberRange } from "../Utils";
+import { Doc, Field, Opt } from "./Doc";
+import { Copy, ToScriptString, ToString } from "./FieldSymbols";
+import { List } from "./List";
+import { ObjectField } from "./ObjectField";
import { ProxyField } from "./Proxy";
import { Cast, NumCast } from "./Types";
-import { List } from "./List";
-import { numberRange } from "../Utils";
+import { Plugins } from "./util";
function optional(propSchema: PropSchema) {
return custom(value => {
@@ -40,28 +41,9 @@ const scriptSchema = createSimpleSchema({
});
async function deserializeScript(script: ScriptField) {
- if (script.script.originalScript === 'copyDragFactory(this.dragFactory)') {
- return (script as any).script = (ScriptField.GetCopyOfDragFactory ?? (ScriptField.GetCopyOfDragFactory = ScriptField.MakeFunction('copyDragFactory(this.dragFactory)')))?.script;
- }
- if (script.script.originalScript === 'links(self)') {
- return (script as any).script = (ScriptField.LinksSelf ?? (ScriptField.LinksSelf = ComputedField.MakeFunction('links(self)')))?.script;
- }
- if (script.script.originalScript === 'openOnRight(copyDragFactory(this.dragFactory))') {
- return (script as any).script = (ScriptField.OpenOnRight ?? (ScriptField.OpenOnRight = ComputedField.MakeFunction('openOnRight(copyDragFactory(this.dragFactory))')))?.script;
- }
- if (script.script.originalScript === 'deiconifyView(self)') {
- return (script as any).script = (ScriptField.DeiconifyView ?? (ScriptField.DeiconifyView = ComputedField.MakeFunction('deiconifyView(self)')))?.script;
- }
- if (script.script.originalScript === 'convertToButtons(dragData)') {
- return (script as any).script = (ScriptField.ConvertToButtons ?? (ScriptField.ConvertToButtons = ComputedField.MakeFunction('convertToButtons(dragData)', { dragData: "DocumentDragData" })))?.script;
- }
- if (script.script.originalScript === 'IsNoviceMode()') {
- return (script as any).script = (ScriptField.NoviceMode ?? (ScriptField.NoviceMode = ComputedField.MakeFunction('IsNoviceMode()')))?.script;
- }
- if (script.script.originalScript === `selectMainMenu(self)`) {
- return (script as any).script = (ScriptField.SelectMenu ?? (ScriptField.SelectMenu = ComputedField.MakeFunction('selectMainMenu(self)')))?.script;
- }
const captures: ProxyField<Doc> = (script as any).captures;
+ const cache = captures ? undefined : ScriptField.GetScriptFieldCache(script.script.originalScript);
+ if (cache) return (script as any).script = cache;
if (captures) {
const doc = (await captures.value())!;
const captured: any = {};
@@ -75,6 +57,7 @@ async function deserializeScript(script: ScriptField) {
throw new Error("Couldn't compile loaded script");
}
(script as any).script = comp;
+ !captures && ScriptField._scriptFieldCache.set(script.script.originalScript, comp);
if (script.setterscript) {
const compset = CompileScript(script.setterscript?.originalScript, script.setterscript.options);
if (!compset.compiled) {
@@ -95,13 +78,9 @@ export class ScriptField extends ObjectField {
@serializable(autoObject())
private captures?: ProxyField<Doc>;
- public static GetCopyOfDragFactory: Opt<ScriptField>;
- public static LinksSelf: Opt<ScriptField>;
- public static OpenOnRight: Opt<ScriptField>;
- public static DeiconifyView: Opt<ScriptField>;
- public static ConvertToButtons: Opt<ScriptField>;
- public static NoviceMode: Opt<ScriptField>;
- public static SelectMenu: Opt<ScriptField>;
+ public static _scriptFieldCache: Map<string, Opt<CompiledScript>> = new Map();
+ public static GetScriptFieldCache(field: string) { return this._scriptFieldCache.get(field); }
+
constructor(script: CompiledScript, setterscript?: CompiledScript) {
super();
@@ -150,7 +129,13 @@ export class ScriptField extends ObjectField {
}
public static CompileScript(script: string, params: object = {}, addReturn = false, capturedVariables?: { [name: string]: Field }) {
const compiled = CompileScript(script, {
- params: { this: Doc?.name || "Doc", self: Doc?.name || "Doc", _last_: "any", ...params },
+ 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
+ _last_: "any", // _last_ is the previous value of a computed field when it is being triggered to re-run.
+ _readOnly_: "boolean", // _readOnly_ is set when a computed field is executed to indicate that it should not have mobx side-effects. used for checking the value of a set function (see FontIconBox)
+ ...params
+ },
typecheck: false,
editable: true,
addReturn: addReturn,
@@ -175,7 +160,7 @@ 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 }, console.log).result;
+ _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;
[Copy](): ObjectField {
@@ -201,19 +186,6 @@ export class ComputedField extends ScriptField {
return getField.compiled ? new ComputedField(getField, setField?.compiled ? setField : undefined) : undefined;
}
}
-Scripting.addGlobal(function setIndexVal(list: any[], index: number, value: any) {
- while (list.length <= index) list.push(undefined);
- list[index] = value;
-}, "sets the value at a given index of a list", "(list: any[], index: number, value: any)");
-
-Scripting.addGlobal(function getIndexVal(list: any[], index: number) {
- return list?.reduce((p, x, i) => (i <= index && x !== undefined) || p === undefined ? x : p, undefined as any);
-}, "returns the value at a given index of a list", "(list: any[], index: number)");
-
-Scripting.addGlobal(function makeScript(script: string) {
- return ScriptField.MakeScript(script);
-}, "returns the value at a given index of a list", "(list: any[], index: number)");
-
export namespace ComputedField {
let useComputed = true;
export function DisableComputedFields() {
@@ -242,4 +214,17 @@ export namespace ComputedField {
}
});
}
-} \ No newline at end of file
+}
+
+ScriptingGlobals.add(function setIndexVal(list: any[], index: number, value: any) {
+ while (list.length <= index) list.push(undefined);
+ list[index] = value;
+}, "sets the value at a given index of a list", "(list: any[], index: number, value: any)");
+
+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);
+}, "returns the value at a given index of a list", "(list: any[], index: number)");
+
+ScriptingGlobals.add(function makeScript(script: string) {
+ return ScriptField.MakeScript(script);
+}, "returns the value at a given index of a list", "(list: any[], index: number)");