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" ;
2
3
import { getPropertyDescriptor } from "./class-model" ;
3
4
import { RegistrationError } from "./errors" ;
4
5
import { $notYetMemoized , $readOnly } from "./symbols" ;
@@ -28,6 +29,10 @@ export class FastGetBuilder {
28
29
return `mqt/${ property } -memo` ;
29
30
}
30
31
32
+ snapshottedViewInputSymbolName ( property : string ) {
33
+ return `mqt/${ property } -svi-memo` ;
34
+ }
35
+
31
36
outerClosureStatements ( className : string ) {
32
37
return this . memoizableProperties
33
38
. map (
@@ -39,30 +44,67 @@ export class FastGetBuilder {
39
44
. join ( "\n" ) ;
40
45
}
41
46
42
- buildGetter ( property : string , descriptor : PropertyDescriptor ) {
47
+ buildViewGetter ( metadata : ViewMetadata | SnapshottedViewMetadata , descriptor : PropertyDescriptor ) {
48
+ const property = metadata . property ;
43
49
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;
51
76
return value;
52
77
}
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
+ }
53
93
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
+ }
57
98
}
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
+ }
62
104
63
105
try {
64
106
const builder = eval ( source ) ;
65
- return builder ( { $readOnly , $memo , $notYetMemoized , getValue : descriptor . get } ) ;
107
+ return builder ( args ) ;
66
108
} catch ( error ) {
67
109
console . error ( `Error building getter for ${ this . klass . name } #${ property } ` ) ;
68
110
console . error ( `Compiled source:\n${ source } ` ) ;
0 commit comments