1- import type { PropertyMetadata , ViewMetadata } from "./class-model" ;
1+ import { snapshotProcessor } from "mobx-state-tree/dist/internal" ;
2+ import type { PropertyMetadata , SnapshottedViewMetadata , ViewMetadata } from "./class-model" ;
23import { getPropertyDescriptor } from "./class-model" ;
34import { RegistrationError } from "./errors" ;
45import { $notYetMemoized , $readOnly } from "./symbols" ;
@@ -28,6 +29,10 @@ export class FastGetBuilder {
2829 return `mqt/${ property } -memo` ;
2930 }
3031
32+ snapshottedViewInputSymbolName ( property : string ) {
33+ return `mqt/${ property } -svi-memo` ;
34+ }
35+
3136 outerClosureStatements ( className : string ) {
3237 return this . memoizableProperties
3338 . map (
@@ -39,30 +44,67 @@ export class FastGetBuilder {
3944 . join ( "\n" ) ;
4045 }
4146
42- buildGetter ( property : string , descriptor : PropertyDescriptor ) {
47+ buildViewGetter ( metadata : ViewMetadata | SnapshottedViewMetadata , descriptor : PropertyDescriptor ) {
48+ const property = metadata . property ;
4349 const $memo = Symbol . for ( this . memoSymbolName ( property ) ) ;
44- const source = `
45- (
46- function build({ $readOnly, $memo, $notYetMemoized, getValue }) {
47- return function get${ property } (model, imports) {
48- if (!this[$readOnly]) return getValue.call(this);
49- let value = this[$memo];
50- if (value !== $notYetMemoized) {
50+
51+ let source ;
52+ let args ;
53+
54+ if ( metadata . type === "snapshotted-view" && metadata . options . createReadOnly ) {
55+ const $snapshotValue = Symbol . for ( this . snapshottedViewInputSymbolName ( property ) ) ;
56+
57+ // this snapshotted view has a hydrator, so we need a special view function for readonly instances that lazily hydrates the snapshotted value
58+ source = `
59+ (
60+ function build({ $readOnly, $memo, $notYetMemoized, $snapshotValue, getValue, hydrate }) {
61+ return function get${ property } (model, imports) {
62+ if (!this[$readOnly]) return getValue.call(this);
63+ let value = this[$memo];
64+ if (value !== $notYetMemoized) {
65+ return value;
66+ }
67+
68+ const dehydratedValue = this[$snapshotValue];
69+ if (typeof dehydratedValue !== "undefined") {
70+ value = hydrate(dehydratedValue, this);
71+ } else {
72+ value = getValue.call(this);
73+ }
74+
75+ this[$memo] = value;
5176 return value;
5277 }
78+ }
79+ )
80+ //# sourceURL=mqt-eval/dynamic/${ this . klass . name } -${ property } -get.js
81+ ` ;
82+ args = { $readOnly, $memo, $snapshotValue, $notYetMemoized, hydrate : metadata . options . createReadOnly , getValue : descriptor . get } ;
83+ } else {
84+ source = `
85+ (
86+ function build({ $readOnly, $memo, $notYetMemoized, getValue }) {
87+ return function get${ property } (model, imports) {
88+ if (!this[$readOnly]) return getValue.call(this);
89+ let value = this[$memo];
90+ if (value !== $notYetMemoized) {
91+ return value;
92+ }
5393
54- value = getValue.call(this);
55- this[$memo] = value;
56- return value;
94+ value = getValue.call(this);
95+ this[$memo] = value;
96+ return value;
97+ }
5798 }
58- }
59- )
60- //# sourceURL=mqt-eval/dynamic/${ this . klass . name } -${ property } -get.js
61- ` ;
99+ )
100+ //# sourceURL=mqt-eval/dynamic/${ this . klass . name } -${ property } -get.js
101+ ` ;
102+ args = { $readOnly, $memo, $notYetMemoized, getValue : descriptor . get } ;
103+ }
62104
63105 try {
64106 const builder = eval ( source ) ;
65- return builder ( { $readOnly , $memo , $notYetMemoized , getValue : descriptor . get } ) ;
107+ return builder ( args ) ;
66108 } catch ( error ) {
67109 console . error ( `Error building getter for ${ this . klass . name } #${ property } ` ) ;
68110 console . error ( `Compiled source:\n${ source } ` ) ;
0 commit comments