@helios-lang/contract-utils 0.2.72 → 0.2.74

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,9 +1,15 @@
1
1
  {
2
2
  "name": "@helios-lang/contract-utils",
3
- "version": "0.2.72",
3
+ "version": "0.2.74",
4
4
  "description": "Convenience and type-safety utilities for using Helios validators from within Typescript",
5
5
  "main": "src/index.js",
6
6
  "types": "types/index.d.ts",
7
+ "exports": {
8
+ "./set-fs-build-cache": "./src/context/set-fs-build-cache.js"
9
+ },
10
+ "sideEffects": [
11
+ "./src/context/set-fs-build-cache.js"
12
+ ],
7
13
  "type": "module",
8
14
  "bin": {
9
15
  "hl2ts": "src/hl2ts.js"
@@ -28,6 +34,7 @@
28
34
  "@helios-lang/cli-utils": "^0.1.10",
29
35
  "@helios-lang/codec-utils": "^0.2.1",
30
36
  "@helios-lang/compiler-utils": "^0.2.1",
37
+ "@helios-lang/crypto": "0.1.17",
31
38
  "@helios-lang/ledger": "^0.5.8",
32
39
  "@helios-lang/type-utils": "^0.1.25",
33
40
  "@helios-lang/uplc": "^0.6.1"
@@ -0,0 +1,310 @@
1
+ import { bytesToHex } from "@helios-lang/codec-utils"
2
+ import {
3
+ MintingPolicyHash,
4
+ ScriptHash,
5
+ StakingValidatorHash,
6
+ ValidatorHash
7
+ } from "@helios-lang/ledger"
8
+ import { None, expectSome } from "@helios-lang/type-utils"
9
+ import { UplcProgramV1, UplcProgramV2, UplcSourceMap } from "@helios-lang/uplc"
10
+ import { Cast } from "../cast/Cast.js"
11
+
12
+ /**
13
+ * @typedef {import("@helios-lang/type-utils").TypeSchema} TypeSchema
14
+ * @typedef {import("@helios-lang/uplc").UplcData} UplcData
15
+ * @typedef {import("@helios-lang/uplc").PlutusVersion} PlutusVersion
16
+ * @typedef {import("@helios-lang/uplc").UplcProgram} UplcProgram
17
+ * @typedef {import("@helios-lang/uplc").UplcProgramV1I} UplcProgramV1I
18
+ * @typedef {import("@helios-lang/uplc").UplcProgramV2I} UplcProgramV2I
19
+ * @typedef {import("@helios-lang/uplc").UplcSourceMapJsonSafe} UplcSourceMapJsonSafe
20
+ * @typedef {import("../cast/index.js").CastConfig} CastConfig
21
+ * @typedef {import("../codegen/LoadedModule.js").LoadedModule} LoadedModule
22
+ * @typedef {import("../codegen/LoadedValidator.js").LoadedValidator} LoadedValidator
23
+ * @typedef {import("./ContractContext.js").AnyContractValidatorContext} AnyContractValidatorContext
24
+ */
25
+
26
+ /**
27
+ * @typedef {{
28
+ * debug?: boolean
29
+ * validators: {[name: string]: AnyContractValidatorContext}
30
+ * userFuncs: {[name: string]: UplcProgram}
31
+ * }} CacheEntry
32
+ */
33
+
34
+ /**
35
+ * @typedef {{[name: string]: {
36
+ * purpose: "minting" | "spending" | "staking" | "mixed"
37
+ * bytes: number[]
38
+ * unoptimizedCborHex?: string
39
+ * unoptimizedIr?: string
40
+ * unoptimizedSourceMap?: UplcSourceMapJsonSafe
41
+ * optimizedCborHex: string
42
+ * optimizedIr?: string
43
+ * optimizedSourceMap?: UplcSourceMapJsonSafe
44
+ * plutusVersion: PlutusVersion
45
+ * castConfig: CastConfig
46
+ * datum?: TypeSchema
47
+ * redeemer: TypeSchema
48
+ * }}} CacheEntryValidatorsJson
49
+ */
50
+
51
+ /**
52
+ * @typedef {{[name: string]: {
53
+ * unoptimizedCborHex?: string
54
+ * unoptimizedIr?: string
55
+ * unoptimizedSourceMap?: UplcSourceMapJsonSafe
56
+ * optimizedCborHex: string
57
+ * optimizedIr?: string
58
+ * optimizedSourceMap?: UplcSourceMapJsonSafe
59
+ * plutusVersion: PlutusVersion
60
+ * }}} CacheEntryUserFuncsJson
61
+ */
62
+
63
+ /**
64
+ * @typedef {{
65
+ * debug?: boolean
66
+ * validators: CacheEntryValidatorsJson
67
+ * userFuncs: CacheEntryUserFuncsJson
68
+ * }} CacheEntryJson
69
+ */
70
+
71
+ /**
72
+ * @param {CacheEntry} entry
73
+ * @returns {CacheEntryJson}
74
+ */
75
+ export function cacheEntryToJsonSafe(entry) {
76
+ /**
77
+ * @type {CacheEntryValidatorsJson}
78
+ */
79
+ const resValidators = {}
80
+
81
+ /**
82
+ * @type {CacheEntryUserFuncsJson}
83
+ */
84
+ const resUserFuncs = {}
85
+
86
+ for (let name in entry.validators) {
87
+ const hash = entry.validators[name]
88
+
89
+ const purpose =
90
+ hash instanceof ValidatorHash
91
+ ? "spending"
92
+ : hash instanceof MintingPolicyHash
93
+ ? "minting"
94
+ : hash instanceof StakingValidatorHash
95
+ ? "staking"
96
+ : hash instanceof ScriptHash
97
+ ? "mixed"
98
+ : "unknown"
99
+ if (purpose == "unknown") {
100
+ throw new Error("unhandled hash type")
101
+ }
102
+
103
+ const redeemer =
104
+ hash.context.redeemer instanceof Cast ? hash.context.redeemer : None
105
+
106
+ if (!redeemer) {
107
+ throw new Error("Redeemer is not a Cast type")
108
+ }
109
+
110
+ /**
111
+ * @type {Option<Cast>}
112
+ */
113
+ let datum = None
114
+
115
+ if (hash.context.datum && hash.context.datum instanceof Cast) {
116
+ datum = hash.context.datum
117
+ }
118
+
119
+ if (["spending", "mixed"].includes(purpose) && !datum) {
120
+ throw new Error("Datum is not a Cast type")
121
+ }
122
+
123
+ /**
124
+ * @type {UplcProgramV1I | UplcProgramV2I}
125
+ */
126
+ const program = hash.context.program
127
+
128
+ resValidators[name] = {
129
+ purpose: purpose,
130
+ bytes: hash.bytes,
131
+ optimizedCborHex: bytesToHex(program.toCbor()),
132
+ unoptimizedCborHex: program.alt
133
+ ? bytesToHex(program.alt.toCbor())
134
+ : undefined,
135
+ optimizedIr:
136
+ /** @type {UplcProgramV2I} */ (program).ir ?? undefined,
137
+ unoptimizedIr:
138
+ /** @type {UplcProgramV2I} */ (program).alt?.ir ?? undefined,
139
+ optimizedSourceMap: UplcSourceMap.fromUplcTerm(
140
+ program.root
141
+ ).toJsonSafe(),
142
+ unoptimizedSourceMap: program.alt
143
+ ? UplcSourceMap.fromUplcTerm(program.alt.root).toJsonSafe()
144
+ : undefined,
145
+ plutusVersion: hash.context.program.plutusVersion,
146
+ castConfig: redeemer.config,
147
+ redeemer: redeemer.schema,
148
+ datum: datum?.schema
149
+ }
150
+ }
151
+
152
+ for (let name in entry.userFuncs) {
153
+ const userFunc = entry.userFuncs[name]
154
+
155
+ resUserFuncs[name] = {
156
+ optimizedCborHex: bytesToHex(userFunc.toCbor()),
157
+ unoptimizedCborHex: /** @type {UplcProgramV2I} */ (userFunc).alt
158
+ ? bytesToHex(
159
+ /** @type {UplcProgramV2I} */ (userFunc).alt.toCbor()
160
+ )
161
+ : undefined,
162
+ optimizedIr: userFunc.ir ?? undefined,
163
+ unoptimizedIr: userFunc.alt?.ir ?? undefined,
164
+ optimizedSourceMap: UplcSourceMap.fromUplcTerm(
165
+ userFunc.root
166
+ ).toJsonSafe(),
167
+ unoptimizedSourceMap: userFunc.alt
168
+ ? UplcSourceMap.fromUplcTerm(userFunc.alt.root).toJsonSafe()
169
+ : undefined,
170
+ plutusVersion: userFunc.plutusVersion
171
+ }
172
+ }
173
+
174
+ return {
175
+ debug: entry.debug ?? false,
176
+ validators: resValidators,
177
+ userFuncs: resUserFuncs
178
+ }
179
+ }
180
+
181
+ /**
182
+ * @param {CacheEntryJson} entry
183
+ * @returns {CacheEntry}
184
+ */
185
+ export function cacheEntryFromJson(entry) {
186
+ /**
187
+ * @type {CacheEntry}
188
+ */
189
+ const res = {
190
+ debug: entry.debug ?? false,
191
+ validators: {},
192
+ userFuncs: {}
193
+ }
194
+
195
+ for (let name in entry.validators) {
196
+ const props = entry.validators[name]
197
+
198
+ /**
199
+ * @type {UplcProgram}
200
+ */
201
+ let program =
202
+ props.plutusVersion == "PlutusScriptV1"
203
+ ? UplcProgramV1.fromCbor(props.optimizedCborHex, {
204
+ ir: props.optimizedIr,
205
+ sourceMap: props.optimizedSourceMap
206
+ })
207
+ : UplcProgramV2.fromCbor(props.optimizedCborHex, {
208
+ ir: props.optimizedIr,
209
+ sourceMap: props.optimizedSourceMap
210
+ })
211
+
212
+ if (props.unoptimizedCborHex) {
213
+ if (program.plutusVersion == "PlutusScriptV1") {
214
+ program = program.withAlt(
215
+ UplcProgramV1.fromCbor(props.unoptimizedCborHex, {
216
+ ir: props.unoptimizedIr,
217
+ sourceMap: props.unoptimizedSourceMap
218
+ })
219
+ )
220
+ } else if (program.plutusVersion == "PlutusScriptV2") {
221
+ program = program.withAlt(
222
+ UplcProgramV2.fromCbor(props.unoptimizedCborHex, {
223
+ ir: props.unoptimizedIr,
224
+ sourceMap: props.unoptimizedSourceMap
225
+ })
226
+ )
227
+ } else {
228
+ throw new Error("unhandled Plutus version")
229
+ }
230
+ }
231
+
232
+ let redeemer = new Cast(props.redeemer, props.castConfig)
233
+
234
+ switch (props.purpose) {
235
+ case "spending": {
236
+ res.validators[name] = new ValidatorHash(props.bytes, {
237
+ datum: new Cast(expectSome(props.datum), props.castConfig),
238
+ redeemer: redeemer,
239
+ program: program
240
+ })
241
+ break
242
+ }
243
+ case "minting": {
244
+ res.validators[name] = new MintingPolicyHash(props.bytes, {
245
+ redeemer: redeemer,
246
+ program: program
247
+ })
248
+ break
249
+ }
250
+ case "staking": {
251
+ res.validators[name] = new StakingValidatorHash(props.bytes, {
252
+ redeemer: redeemer,
253
+ program: program
254
+ })
255
+ break
256
+ }
257
+ case "mixed": {
258
+ res.validators[name] = new ScriptHash(props.bytes, {
259
+ datum: new Cast(expectSome(props.datum), props.castConfig),
260
+ redeemer: redeemer,
261
+ program: program
262
+ })
263
+ break
264
+ }
265
+ default:
266
+ throw new Error("unhandled purpose")
267
+ }
268
+ }
269
+
270
+ for (let name in entry.userFuncs) {
271
+ const props = entry.userFuncs[name]
272
+
273
+ /**
274
+ * @type {UplcProgram}
275
+ */
276
+ let program =
277
+ props.plutusVersion == "PlutusScriptV1"
278
+ ? UplcProgramV1.fromCbor(props.optimizedCborHex, {
279
+ ir: props.optimizedIr,
280
+ sourceMap: props.optimizedSourceMap
281
+ })
282
+ : UplcProgramV2.fromCbor(props.optimizedCborHex, {
283
+ ir: props.optimizedIr,
284
+ sourceMap: props.optimizedSourceMap
285
+ })
286
+
287
+ if (props.unoptimizedCborHex) {
288
+ if (program.plutusVersion == "PlutusScriptV1") {
289
+ program = program.withAlt(
290
+ UplcProgramV1.fromCbor(props.unoptimizedCborHex, {
291
+ ir: props.unoptimizedIr,
292
+ sourceMap: props.unoptimizedSourceMap
293
+ })
294
+ )
295
+ } else if (program.plutusVersion == "PlutusScriptV2") {
296
+ program = program.withAlt(
297
+ UplcProgramV2.fromCbor(props.unoptimizedCborHex, {
298
+ ir: props.unoptimizedIr,
299
+ sourceMap: props.unoptimizedSourceMap
300
+ })
301
+ )
302
+ } else {
303
+ throw new Error("unhandled Plutus version")
304
+ }
305
+ }
306
+ res.userFuncs[name] = program
307
+ }
308
+
309
+ return res
310
+ }
@@ -47,6 +47,7 @@ export class ContractContextBuilder {
47
47
  validators
48
48
 
49
49
  /**
50
+ * @private
50
51
  * @readonly
51
52
  * @type {Ms}
52
53
  */
@@ -118,12 +119,22 @@ export class ContractContextBuilder {
118
119
  const castConfig = { isMainnet: props.isMainnet }
119
120
  const lib = loadCompilerLib()
120
121
 
122
+ // generate a cache key
123
+ const key = contractContextCache.genCacheKey({
124
+ version: lib.version,
125
+ debug: !!props.debug,
126
+ isMainnet: props.isMainnet,
127
+ validators: this.validators,
128
+ modules: this.modules,
129
+ parameters: props.parameters ?? {}
130
+ })
131
+
121
132
  const dagCompiler = new DagCompiler(lib, {
122
133
  debug: props.debug ?? false,
123
134
  ...castConfig
124
135
  })
125
136
 
126
- const cached = contractContextCache.shift()
137
+ const cached = contractContextCache.get(key)
127
138
 
128
139
  const compiled =
129
140
  cached ||
@@ -134,8 +145,7 @@ export class ContractContextBuilder {
134
145
  props.expectedHashes
135
146
  )
136
147
 
137
- // TODO: adapt to use generic cache interface
138
- contractContextCache.push(compiled)
148
+ contractContextCache.set(key, compiled)
139
149
 
140
150
  if (props.dumpHashes) {
141
151
  for (let name in compiled.validators) {
@@ -1,89 +1,57 @@
1
- import { bytesToHex } from "@helios-lang/codec-utils"
2
- import {
3
- MintingPolicyHash,
4
- ScriptHash,
5
- StakingValidatorHash,
6
- ValidatorHash
7
- } from "@helios-lang/ledger"
8
- import { None, expectSome } from "@helios-lang/type-utils"
9
- import { UplcProgramV1, UplcProgramV2, UplcSourceMap } from "@helios-lang/uplc"
10
- import { Cast } from "../cast/Cast.js"
1
+ import { bytesToHex, encodeUtf8 } from "@helios-lang/codec-utils"
2
+ import { blake2b } from "@helios-lang/crypto"
3
+ import { JSON, None } from "@helios-lang/type-utils"
4
+ import { cacheEntryFromJson, cacheEntryToJsonSafe } from "./CacheEntry.js"
11
5
 
12
6
  /**
13
- * @typedef {import("@helios-lang/uplc").PlutusVersion} PlutusVersion
7
+ * @typedef {import("@helios-lang/uplc").UplcData} UplcData
14
8
  * @typedef {import("@helios-lang/uplc").UplcProgram} UplcProgram
15
- * @typedef {import("@helios-lang/uplc").UplcProgramV1I} UplcProgramV1I
16
- * @typedef {import("@helios-lang/uplc").UplcProgramV2I} UplcProgramV2I
17
- * @typedef {import("@helios-lang/uplc").UplcSourceMapJsonSafe} UplcSourceMapJsonSafe
18
- * @typedef {import("../cast/index.js").CastConfig} CastConfig
19
- * @typedef {import("../codegen/index.js").TypeSchema} TypeSchema
20
- * @typedef {import("./ContractContext.js").AnyContractValidatorContext} AnyContractValidatorContext
9
+ * @typedef {import("../codegen/LoadedModule.js").LoadedModule} LoadedModule
10
+ * @typedef {import("../codegen/LoadedValidator.js").LoadedValidator} LoadedValidator
11
+ * @typedef {import("./CacheEntry.js").CacheEntry} CacheEntry
12
+ * @typedef {import("./CacheEntry.js").CacheEntryJson} CacheEntryJson
13
+ * @typedef {import("./CacheEntry.js").CacheEntryUserFuncsJson} CacheEntryUserFuncsJson
14
+ * @typedef {import("./CacheEntry.js").CacheEntryValidatorsJson} CacheEntryValidatorsJson
21
15
  */
22
16
 
23
17
  /**
24
18
  * @typedef {{
25
- * debug?: boolean
26
- * validators: {[name: string]: AnyContractValidatorContext}
27
- * userFuncs: {[name: string]: UplcProgram}
28
- * }} CacheEntry
29
- */
30
-
31
- /**
32
- * @typedef {{[name: string]: {
33
- * purpose: "minting" | "spending" | "staking" | "mixed"
34
- * bytes: number[]
35
- * unoptimizedCborHex?: string
36
- * unoptimizedIr?: string
37
- * unoptimizedSourceMap?: UplcSourceMapJsonSafe
38
- * optimizedCborHex: string
39
- * optimizedIr?: string
40
- * optimizedSourceMap?: UplcSourceMapJsonSafe
41
- * plutusVersion: PlutusVersion
42
- * castConfig: CastConfig
43
- * datum?: TypeSchema
44
- * redeemer: TypeSchema
45
- * }}} CacheEntryValidatorsJson
46
- */
47
-
48
- /**
49
- * @typedef {{[name: string]: {
50
- * unoptimizedCborHex?: string
51
- * unoptimizedIr?: string
52
- * unoptimizedSourceMap?: UplcSourceMapJsonSafe
53
- * optimizedCborHex: string
54
- * optimizedIr?: string
55
- * optimizedSourceMap?: UplcSourceMapJsonSafe
56
- * plutusVersion: PlutusVersion
57
- * }}} CacheEntryUserFuncsJson
58
- */
59
-
60
- /**
61
- * @typedef {{
62
- * debug?: boolean
63
- * validators: CacheEntryValidatorsJson
64
- * userFuncs: CacheEntryUserFuncsJson
65
- * }} CacheEntryJson
19
+ * has(key: string): boolean
20
+ * get(key: string): JsonSafe
21
+ * set(key: string, entry: JsonSafe): void
22
+ * }} ExplicitCache
66
23
  */
67
24
 
68
25
  class ContractContextCache {
69
26
  /**
27
+ * Used by esbuild-plugin
28
+ * @private
70
29
  * @type {CacheEntry[]}
71
30
  */
72
- cache
31
+ positionalCache
32
+
33
+ /**
34
+ * Explicitly specified by user by calling setBuildCache()
35
+ * @readwrite
36
+ * @type {Option<ExplicitCache>}
37
+ */
38
+ explicitCache
73
39
 
74
40
  /**
75
41
  * Load count
42
+ * @private
76
43
  * @type {number}
77
44
  */
78
45
  i
79
46
 
80
47
  /**
48
+ * @private
81
49
  * @type {boolean}
82
50
  */
83
51
  enabled
84
52
 
85
53
  constructor() {
86
- this.cache = []
54
+ this.positionalCache = []
87
55
  this.enabled = false
88
56
  this.i = 0
89
57
  }
@@ -93,292 +61,94 @@ class ContractContextCache {
93
61
  }
94
62
 
95
63
  /**
96
- * @param {CacheEntryJson[]} json
64
+ * Key is only generated if the explicitCache is set
65
+ * @param {{
66
+ * version: string
67
+ * debug: boolean
68
+ * isMainnet: boolean
69
+ * validators: Record<string, LoadedValidator>
70
+ * modules: Record<string, LoadedModule>
71
+ * parameters: Record<string, UplcData>
72
+ * }} props
73
+ * @returns {string}
97
74
  */
98
- load(json) {
99
- this.cache = json.map((entry) => {
100
- /**
101
- * @type {CacheEntry}
102
- */
103
- const res = {
104
- debug: entry.debug ?? false,
105
- validators: {},
106
- userFuncs: {}
75
+ genCacheKey(props) {
76
+ if (this.explicitCache) {
77
+ const obj = {
78
+ version: props.version,
79
+ debug: props.debug,
80
+ isMainnet: props.isMainnet,
81
+ validators: Object.keys(props.validators)
82
+ .sort()
83
+ .map((k) => props.validators[k].$sourceCode),
84
+ modules: Object.keys(props.modules)
85
+ .sort()
86
+ .map((k) => props.modules[k].$sourceCode),
87
+ parameters: Object.keys(props.parameters)
88
+ .sort()
89
+ .map((k) => props.parameters[k].toSchemaJson())
107
90
  }
108
91
 
109
- for (let name in entry.validators) {
110
- const props = entry.validators[name]
111
-
112
- /**
113
- * @type {UplcProgram}
114
- */
115
- let program =
116
- props.plutusVersion == "PlutusScriptV1"
117
- ? UplcProgramV1.fromCbor(props.optimizedCborHex, {
118
- ir: props.optimizedIr,
119
- sourceMap: props.optimizedSourceMap
120
- })
121
- : UplcProgramV2.fromCbor(props.optimizedCborHex, {
122
- ir: props.optimizedIr,
123
- sourceMap: props.optimizedSourceMap
124
- })
125
-
126
- if (props.unoptimizedCborHex) {
127
- if (program.plutusVersion == "PlutusScriptV1") {
128
- program = program.withAlt(
129
- UplcProgramV1.fromCbor(props.unoptimizedCborHex, {
130
- ir: props.unoptimizedIr,
131
- sourceMap: props.unoptimizedSourceMap
132
- })
133
- )
134
- } else if (program.plutusVersion == "PlutusScriptV2") {
135
- program = program.withAlt(
136
- UplcProgramV2.fromCbor(props.unoptimizedCborHex, {
137
- ir: props.unoptimizedIr,
138
- sourceMap: props.unoptimizedSourceMap
139
- })
140
- )
141
- } else {
142
- throw new Error("unhandled Plutus version")
143
- }
144
- }
145
-
146
- let redeemer = new Cast(props.redeemer, props.castConfig)
147
-
148
- switch (props.purpose) {
149
- case "spending": {
150
- res.validators[name] = new ValidatorHash(props.bytes, {
151
- datum: new Cast(
152
- expectSome(props.datum),
153
- props.castConfig
154
- ),
155
- redeemer: redeemer,
156
- program: program
157
- })
158
- break
159
- }
160
- case "minting": {
161
- res.validators[name] = new MintingPolicyHash(
162
- props.bytes,
163
- {
164
- redeemer: redeemer,
165
- program: program
166
- }
167
- )
168
- break
169
- }
170
- case "staking": {
171
- res.validators[name] = new StakingValidatorHash(
172
- props.bytes,
173
- {
174
- redeemer: redeemer,
175
- program: program
176
- }
177
- )
178
- break
179
- }
180
- case "mixed": {
181
- res.validators[name] = new ScriptHash(props.bytes, {
182
- datum: new Cast(
183
- expectSome(props.datum),
184
- props.castConfig
185
- ),
186
- redeemer: redeemer,
187
- program: program
188
- })
189
- break
190
- }
191
- default:
192
- throw new Error("unhandled purpose")
193
- }
194
- }
92
+ // TODO: if this hashing method is slow fall back to system defined hashing
93
+ const digest = blake2b(encodeUtf8(JSON.stringify(obj)))
195
94
 
196
- for (let name in entry.userFuncs) {
197
- const props = entry.userFuncs[name]
198
-
199
- /**
200
- * @type {UplcProgram}
201
- */
202
- let program =
203
- props.plutusVersion == "PlutusScriptV1"
204
- ? UplcProgramV1.fromCbor(props.optimizedCborHex, {
205
- ir: props.optimizedIr,
206
- sourceMap: props.optimizedSourceMap
207
- })
208
- : UplcProgramV2.fromCbor(props.optimizedCborHex, {
209
- ir: props.optimizedIr,
210
- sourceMap: props.optimizedSourceMap
211
- })
212
-
213
- if (props.unoptimizedCborHex) {
214
- if (program.plutusVersion == "PlutusScriptV1") {
215
- program = program.withAlt(
216
- UplcProgramV1.fromCbor(props.unoptimizedCborHex, {
217
- ir: props.unoptimizedIr,
218
- sourceMap: props.unoptimizedSourceMap
219
- })
220
- )
221
- } else if (program.plutusVersion == "PlutusScriptV2") {
222
- program = program.withAlt(
223
- UplcProgramV2.fromCbor(props.unoptimizedCborHex, {
224
- ir: props.unoptimizedIr,
225
- sourceMap: props.unoptimizedSourceMap
226
- })
227
- )
228
- } else {
229
- throw new Error("unhandled Plutus version")
230
- }
231
- }
232
- res.userFuncs[name] = program
233
- }
95
+ return bytesToHex(digest)
96
+ } else {
97
+ return ""
98
+ }
99
+ }
234
100
 
235
- return res
236
- })
101
+ /**
102
+ * @param {CacheEntryJson[]} json
103
+ */
104
+ load(json) {
105
+ this.positionalCache = json.map(cacheEntryFromJson)
237
106
  }
238
107
 
239
108
  /**
240
- * @param {CacheEntry} hashes
109
+ * @param {string} key - empty string is used to set positional cache (eg. for esbuild-plugn)
110
+ * @param {CacheEntry} entry
241
111
  */
242
- push(hashes) {
243
- if (this.enabled) {
244
- this.cache.push(hashes)
112
+ set(key, entry) {
113
+ if (key != "" && this.explicitCache) {
114
+ this.explicitCache.set(key, cacheEntryToJsonSafe(entry))
115
+ } else if (this.enabled) {
116
+ this.positionalCache.push(entry)
245
117
  }
246
118
  }
247
119
 
248
120
  /**
121
+ * @param {string} key - empty string is used to access positional cache (eg. for esbuild-plugn)
249
122
  * @returns {Option<CacheEntry>}
250
123
  */
251
- shift() {
252
- if (this.i >= this.cache.length) {
124
+ get(key) {
125
+ if (key != "") {
126
+ if (this.explicitCache && this.explicitCache.has(key)) {
127
+ return cacheEntryFromJson(
128
+ /** @type {CacheEntryJson} */ (this.explicitCache.get(key))
129
+ )
130
+ }
131
+
253
132
  return None
254
- }
133
+ } else {
134
+ if (this.i >= this.positionalCache.length) {
135
+ // TODO: lookup in explicitCache
136
+ return None
137
+ }
255
138
 
256
- const res = this.cache[this.i]
139
+ const res = this.positionalCache[this.i]
257
140
 
258
- this.i += 1
141
+ this.i += 1
259
142
 
260
- return res
143
+ return res
144
+ }
261
145
  }
262
146
 
263
147
  /**
264
148
  * @return {CacheEntryJson[]}
265
149
  */
266
150
  toJson() {
267
- return this.cache.map((entry) => {
268
- /**
269
- * @type {CacheEntryValidatorsJson}
270
- */
271
- const resValidators = {}
272
-
273
- /**
274
- * @type {CacheEntryUserFuncsJson}
275
- */
276
- const resUserFuncs = {}
277
-
278
- for (let name in entry.validators) {
279
- const hash = entry.validators[name]
280
-
281
- const purpose =
282
- hash instanceof ValidatorHash
283
- ? "spending"
284
- : hash instanceof MintingPolicyHash
285
- ? "minting"
286
- : hash instanceof StakingValidatorHash
287
- ? "staking"
288
- : hash instanceof ScriptHash
289
- ? "mixed"
290
- : "unknown"
291
- if (purpose == "unknown") {
292
- throw new Error("unhandled hash type")
293
- }
294
-
295
- const redeemer =
296
- hash.context.redeemer instanceof Cast
297
- ? hash.context.redeemer
298
- : None
299
-
300
- if (!redeemer) {
301
- throw new Error("Redeemer is not a Cast type")
302
- }
303
-
304
- /**
305
- * @type {Option<Cast>}
306
- */
307
- let datum = None
308
-
309
- if (hash.context.datum && hash.context.datum instanceof Cast) {
310
- datum = hash.context.datum
311
- }
312
-
313
- if (["spending", "mixed"].includes(purpose) && !datum) {
314
- throw new Error("Datum is not a Cast type")
315
- }
316
-
317
- /**
318
- * @type {UplcProgramV1I | UplcProgramV2I}
319
- */
320
- const program = hash.context.program
321
-
322
- resValidators[name] = {
323
- purpose: purpose,
324
- bytes: hash.bytes,
325
- optimizedCborHex: bytesToHex(program.toCbor()),
326
- unoptimizedCborHex: program.alt
327
- ? bytesToHex(program.alt.toCbor())
328
- : undefined,
329
- optimizedIr:
330
- /** @type {UplcProgramV2I} */ (program).ir ?? undefined,
331
- unoptimizedIr:
332
- /** @type {UplcProgramV2I} */ (program).alt?.ir ??
333
- undefined,
334
- optimizedSourceMap: UplcSourceMap.fromUplcTerm(
335
- program.root
336
- ).toJsonSafe(),
337
- unoptimizedSourceMap: program.alt
338
- ? UplcSourceMap.fromUplcTerm(
339
- program.alt.root
340
- ).toJsonSafe()
341
- : undefined,
342
- plutusVersion: hash.context.program.plutusVersion,
343
- castConfig: redeemer.config,
344
- redeemer: redeemer.schema,
345
- datum: datum?.schema
346
- }
347
- }
348
-
349
- for (let name in entry.userFuncs) {
350
- const userFunc = entry.userFuncs[name]
351
-
352
- resUserFuncs[name] = {
353
- optimizedCborHex: bytesToHex(userFunc.toCbor()),
354
- unoptimizedCborHex: /** @type {UplcProgramV2I} */ (userFunc)
355
- .alt
356
- ? bytesToHex(
357
- /** @type {UplcProgramV2I} */ (
358
- userFunc
359
- ).alt.toCbor()
360
- )
361
- : undefined,
362
- optimizedIr: userFunc.ir ?? undefined,
363
- unoptimizedIr: userFunc.alt?.ir ?? undefined,
364
- optimizedSourceMap: UplcSourceMap.fromUplcTerm(
365
- userFunc.root
366
- ).toJsonSafe(),
367
- unoptimizedSourceMap: userFunc.alt
368
- ? UplcSourceMap.fromUplcTerm(
369
- userFunc.alt.root
370
- ).toJsonSafe()
371
- : undefined,
372
- plutusVersion: userFunc.plutusVersion
373
- }
374
- }
375
-
376
- return {
377
- debug: entry.debug ?? false,
378
- validators: resValidators,
379
- userFuncs: resUserFuncs
380
- }
381
- })
151
+ return this.positionalCache.map(cacheEntryToJsonSafe)
382
152
  }
383
153
  }
384
154
 
@@ -0,0 +1,81 @@
1
+ import { contractContextCache } from "./ContractContextCache.js"
2
+
3
+ /**
4
+ * @typedef {import("./ContractContextCache.js").ExplicitCache} ExplicitCache
5
+ */
6
+
7
+ // uses same storage strategy as esbuild-plugin
8
+ /**
9
+ * @implements {ExplicitCache}
10
+ */
11
+ class FileSystemCache {
12
+ /**
13
+ * @private
14
+ * @type {typeof import("node:fs")}
15
+ */
16
+ fs
17
+
18
+ /**
19
+ * @private
20
+ * @type {typeof import("node:os")}
21
+ */
22
+ os
23
+
24
+ /**
25
+ * @private
26
+ * @type {typeof import("node:path")}
27
+ */
28
+ path
29
+
30
+ /**
31
+ * @private
32
+ * @type {string}
33
+ */
34
+ cacheDir
35
+
36
+ constructor() {
37
+ this.fs = require("node:fs")
38
+ this.os = require("node:os")
39
+ this.path = require("node:path")
40
+ this.cacheDir = this.path.join(this.os.tmpdir(), "helios-cache")
41
+
42
+ if (!this.fs.existsSync(this.cacheDir)) {
43
+ this.fs.mkdirSync(this.cacheDir, {
44
+ recursive: true
45
+ })
46
+ }
47
+ }
48
+
49
+ /**
50
+ * @private
51
+ * @param {string} key
52
+ */
53
+ genPath(key) {
54
+ return this.path.join(this.cacheDir, key + ".json")
55
+ }
56
+
57
+ /**
58
+ * @param {string} key
59
+ */
60
+ has(key) {
61
+ return this.fs.existsSync(this.genPath(key))
62
+ }
63
+
64
+ /**
65
+ * @param {string} key
66
+ * @returns {JsonSafe}
67
+ */
68
+ get(key) {
69
+ return JSON.parse(this.fs.readFileSync(this.genPath(key)).toString())
70
+ }
71
+
72
+ /**
73
+ * @param {string} key
74
+ * @param {JsonSafe} obj
75
+ */
76
+ set(key, obj) {
77
+ this.fs.writeFileSync(this.genPath(key), JSON.stringify(obj))
78
+ }
79
+ }
80
+
81
+ contractContextCache.explicitCache = new FileSystemCache()
package/src/index.js CHANGED
@@ -3,3 +3,8 @@ export * from "./context/index.js"
3
3
  export { typeCheckFiles, typeCheckScripts } from "./compiler/ops.js"
4
4
  export { LoadedScriptsWriter } from "./codegen/LoadedScriptsWriter.js"
5
5
  export { loadCompilerLib } from "./compiler/ops.js"
6
+
7
+ /**
8
+ * @typedef {import("./codegen/index.js").LoadedValidator} LoadedValidator
9
+ * @typedef {import("./codegen/index.js").LoadedModule} LoadedModule
10
+ */
@@ -0,0 +1,117 @@
1
+ /**
2
+ * @typedef {import("@helios-lang/type-utils").TypeSchema} TypeSchema
3
+ * @typedef {import("@helios-lang/uplc").UplcData} UplcData
4
+ * @typedef {import("@helios-lang/uplc").PlutusVersion} PlutusVersion
5
+ * @typedef {import("@helios-lang/uplc").UplcProgram} UplcProgram
6
+ * @typedef {import("@helios-lang/uplc").UplcProgramV1I} UplcProgramV1I
7
+ * @typedef {import("@helios-lang/uplc").UplcProgramV2I} UplcProgramV2I
8
+ * @typedef {import("@helios-lang/uplc").UplcSourceMapJsonSafe} UplcSourceMapJsonSafe
9
+ * @typedef {import("../cast/index.js").CastConfig} CastConfig
10
+ * @typedef {import("../codegen/LoadedModule.js").LoadedModule} LoadedModule
11
+ * @typedef {import("../codegen/LoadedValidator.js").LoadedValidator} LoadedValidator
12
+ * @typedef {import("./ContractContext.js").AnyContractValidatorContext} AnyContractValidatorContext
13
+ */
14
+ /**
15
+ * @typedef {{
16
+ * debug?: boolean
17
+ * validators: {[name: string]: AnyContractValidatorContext}
18
+ * userFuncs: {[name: string]: UplcProgram}
19
+ * }} CacheEntry
20
+ */
21
+ /**
22
+ * @typedef {{[name: string]: {
23
+ * purpose: "minting" | "spending" | "staking" | "mixed"
24
+ * bytes: number[]
25
+ * unoptimizedCborHex?: string
26
+ * unoptimizedIr?: string
27
+ * unoptimizedSourceMap?: UplcSourceMapJsonSafe
28
+ * optimizedCborHex: string
29
+ * optimizedIr?: string
30
+ * optimizedSourceMap?: UplcSourceMapJsonSafe
31
+ * plutusVersion: PlutusVersion
32
+ * castConfig: CastConfig
33
+ * datum?: TypeSchema
34
+ * redeemer: TypeSchema
35
+ * }}} CacheEntryValidatorsJson
36
+ */
37
+ /**
38
+ * @typedef {{[name: string]: {
39
+ * unoptimizedCborHex?: string
40
+ * unoptimizedIr?: string
41
+ * unoptimizedSourceMap?: UplcSourceMapJsonSafe
42
+ * optimizedCborHex: string
43
+ * optimizedIr?: string
44
+ * optimizedSourceMap?: UplcSourceMapJsonSafe
45
+ * plutusVersion: PlutusVersion
46
+ * }}} CacheEntryUserFuncsJson
47
+ */
48
+ /**
49
+ * @typedef {{
50
+ * debug?: boolean
51
+ * validators: CacheEntryValidatorsJson
52
+ * userFuncs: CacheEntryUserFuncsJson
53
+ * }} CacheEntryJson
54
+ */
55
+ /**
56
+ * @param {CacheEntry} entry
57
+ * @returns {CacheEntryJson}
58
+ */
59
+ export function cacheEntryToJsonSafe(entry: CacheEntry): CacheEntryJson;
60
+ /**
61
+ * @param {CacheEntryJson} entry
62
+ * @returns {CacheEntry}
63
+ */
64
+ export function cacheEntryFromJson(entry: CacheEntryJson): CacheEntry;
65
+ export type TypeSchema = import("@helios-lang/type-utils").TypeSchema;
66
+ export type UplcData = import("@helios-lang/uplc").UplcData;
67
+ export type PlutusVersion = import("@helios-lang/uplc").PlutusVersion;
68
+ export type UplcProgram = import("@helios-lang/uplc").UplcProgram;
69
+ export type UplcProgramV1I = import("@helios-lang/uplc").UplcProgramV1I;
70
+ export type UplcProgramV2I = import("@helios-lang/uplc").UplcProgramV2I;
71
+ export type UplcSourceMapJsonSafe = import("@helios-lang/uplc").UplcSourceMapJsonSafe;
72
+ export type CastConfig = import("../cast/index.js").CastConfig;
73
+ export type LoadedModule = import("../codegen/LoadedModule.js").LoadedModule;
74
+ export type LoadedValidator = import("../codegen/LoadedValidator.js").LoadedValidator;
75
+ export type AnyContractValidatorContext = import("./ContractContext.js").AnyContractValidatorContext;
76
+ export type CacheEntry = {
77
+ debug?: boolean;
78
+ validators: {
79
+ [name: string]: AnyContractValidatorContext;
80
+ };
81
+ userFuncs: {
82
+ [name: string]: UplcProgram;
83
+ };
84
+ };
85
+ export type CacheEntryValidatorsJson = {
86
+ [name: string]: {
87
+ purpose: "minting" | "spending" | "staking" | "mixed";
88
+ bytes: number[];
89
+ unoptimizedCborHex?: string;
90
+ unoptimizedIr?: string;
91
+ unoptimizedSourceMap?: UplcSourceMapJsonSafe;
92
+ optimizedCborHex: string;
93
+ optimizedIr?: string;
94
+ optimizedSourceMap?: UplcSourceMapJsonSafe;
95
+ plutusVersion: PlutusVersion;
96
+ castConfig: CastConfig;
97
+ datum?: TypeSchema;
98
+ redeemer: TypeSchema;
99
+ };
100
+ };
101
+ export type CacheEntryUserFuncsJson = {
102
+ [name: string]: {
103
+ unoptimizedCborHex?: string;
104
+ unoptimizedIr?: string;
105
+ unoptimizedSourceMap?: UplcSourceMapJsonSafe;
106
+ optimizedCborHex: string;
107
+ optimizedIr?: string;
108
+ optimizedSourceMap?: UplcSourceMapJsonSafe;
109
+ plutusVersion: PlutusVersion;
110
+ };
111
+ };
112
+ export type CacheEntryJson = {
113
+ debug?: boolean;
114
+ validators: CacheEntryValidatorsJson;
115
+ userFuncs: CacheEntryUserFuncsJson;
116
+ };
117
+ //# sourceMappingURL=CacheEntry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CacheEntry.d.ts","sourceRoot":"","sources":["../../src/context/CacheEntry.js"],"names":[],"mappings":"AAWA;;;;;;;;;;;;GAYG;AAEH;;;;;;GAMG;AAEH;;;;;;;;;;;;;;;GAeG;AAEH;;;;;;;;;;GAUG;AAEH;;;;;;GAMG;AAEH;;;GAGG;AACH,4CAHW,UAAU,GACR,cAAc,CA0G1B;AAED;;;GAGG;AACH,0CAHW,cAAc,GACZ,UAAU,CA+HtB;yBAzSY,OAAO,yBAAyB,EAAE,UAAU;uBAC5C,OAAO,mBAAmB,EAAE,QAAQ;4BACpC,OAAO,mBAAmB,EAAE,aAAa;0BACzC,OAAO,mBAAmB,EAAE,WAAW;6BACvC,OAAO,mBAAmB,EAAE,cAAc;6BAC1C,OAAO,mBAAmB,EAAE,cAAc;oCAC1C,OAAO,mBAAmB,EAAE,qBAAqB;yBACjD,OAAO,kBAAkB,EAAE,UAAU;2BACrC,OAAO,4BAA4B,EAAE,YAAY;8BACjD,OAAO,+BAA+B,EAAE,eAAe;0CACvD,OAAO,sBAAsB,EAAE,2BAA2B;yBAI1D;IACR,KAAK,CAAC,EAAE,OAAO,CAAA;IACf,UAAU,EAAE;QAAC,CAAC,IAAI,EAAE,MAAM,GAAG,2BAA2B,CAAA;KAAC,CAAA;IACzD,SAAS,EAAE;QAAC,CAAC,IAAI,EAAE,MAAM,GAAG,WAAW,CAAA;KAAC,CAAA;CACzC;uCAIS;IAAC,CAAC,IAAI,EAAE,MAAM,GAAG;QACvB,OAAO,EAAE,SAAS,GAAG,UAAU,GAAG,SAAS,GAAG,OAAO,CAAA;QACrD,KAAK,EAAE,MAAM,EAAE,CAAA;QACf,kBAAkB,CAAC,EAAE,MAAM,CAAA;QAC3B,aAAa,CAAC,EAAE,MAAM,CAAA;QACtB,oBAAoB,CAAC,EAAE,qBAAqB,CAAA;QAC5C,gBAAgB,EAAE,MAAM,CAAA;QACxB,WAAW,CAAC,EAAE,MAAM,CAAA;QACpB,kBAAkB,CAAC,EAAE,qBAAqB,CAAA;QAC1C,aAAa,EAAE,aAAa,CAAA;QAC5B,UAAU,EAAE,UAAU,CAAA;QACtB,KAAK,CAAC,EAAE,UAAU,CAAA;QAClB,QAAQ,EAAE,UAAU,CAAA;KACrB,CAAA;CAAC;sCAIM;IAAC,CAAC,IAAI,EAAE,MAAM,GAAG;QACzB,kBAAkB,CAAC,EAAE,MAAM,CAAA;QAC3B,aAAa,CAAC,EAAE,MAAM,CAAA;QACtB,oBAAoB,CAAC,EAAE,qBAAqB,CAAA;QAC5C,gBAAgB,EAAE,MAAM,CAAA;QACxB,WAAW,CAAC,EAAE,MAAM,CAAA;QACpB,kBAAkB,CAAC,EAAE,qBAAqB,CAAA;QAC1C,aAAa,EAAE,aAAa,CAAA;KAC7B,CAAA;CAAC;6BAIQ;IACR,KAAK,CAAC,EAAE,OAAO,CAAA;IACf,UAAU,EAAE,wBAAwB,CAAA;IACpC,SAAS,EAAE,uBAAuB,CAAA;CACnC"}
@@ -50,10 +50,11 @@ export class ContractContextBuilder<Vs extends {
50
50
  */
51
51
  private readonly validators;
52
52
  /**
53
+ * @private
53
54
  * @readonly
54
55
  * @type {Ms}
55
56
  */
56
- readonly modules: Ms;
57
+ private readonly modules;
57
58
  /**
58
59
  * @template {LoadedValidator} V
59
60
  * @param {V} validator
@@ -1 +1 @@
1
- {"version":3,"file":"ContractContextBuilder.d.ts","sourceRoot":"","sources":["../../src/context/ContractContextBuilder.js"],"names":[],"mappings":"AAMA;;;;;;GAMG;AAEH;;;GAGG;AAEH;;;;GAIG;AAEH;;;;;;;;;GASG;AAEH;;;GAGG;AACH,oCAHiD,EAAE,SAAtC;IAAE,CAAC,IAAI,EAAE,MAAM,GAAG,eAAe,CAAA;CAAE,EACF,EAAE,SAAnC;IAAE,CAAC,IAAI,EAAE,MAAM,GAAG,YAAY,CAAA;CAAE;IA0BzC;;OAEG;IACH,gBAFa,sBAAsB,CAAC,EAAE,EAAE,EAAE,CAAC,CAI1C;IAfD;;;;OAIG;IACH,sBAGC;IArBD;;;;OAIG;IACH,4BAAU;IAEV;;;OAGG;IACH,kBAFU,EAAE,CAEL;IAmBP;;;;;;;OAOG;IACH,KAP+B,CAAC,SAAlB,eAAgB,aACnB,CAAC,GACC,sBAAsB,CAC9B,EAAE,GAAG,GAAE,CAAe,IAAV,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,GAAC,EAC3B,EAAE,GAAG,mBAAmB,CAAC,CAAC,CAAC,CAC5B,CAeH;IAED;;;;;;;OAOG;IACH,WAP4B,CAAC,SAAf,YAAa,KAChB,CAAC,GACC,sBAAsB,CAC9B,EAAE,EACF,EAAE,GAAG,GAAE,CAAe,IAAV,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,GAAC,CAC5B,CAUH;IAED;;;OAGG;IACH,aAHW,yBAAyB,GACvB,eAAe,CAAC,EAAE,EAAE,EAAE,CAAC,CA6GnC;CACJ;uBAzNY,OAAO,mBAAmB,EAAE,QAAQ;yBACpC,OAAO,kBAAkB,EAAE,UAAU;2BACrC,OAAO,4BAA4B,EAAE,YAAY;8BACjD,OAAO,+BAA+B,EAAE,eAAe;0BACvD,OAAO,sBAAsB,EAAE,WAAW;gCAIxB,CAAC,SAAlB,eAAgB,IACjB,OAAO,+BAA+B,EAAE,mBAAmB,CAAC,CAAC,CAAC;4BAI1B,EAAE,SAAtC;IAAE,CAAC,IAAI,EAAE,MAAM,GAAG,eAAe,CAAA;CAAE,EACF,EAAE,SAAnC;IAAE,CAAC,IAAI,EAAE,MAAM,GAAG,YAAY,CAAA;CAAE,IAChC,OAAO,sBAAsB,EAAE,eAAe,CAAC,EAAE,EAAE,EAAE,CAAC;;;;wCAKtD;IACR,SAAS,EAAE,OAAO,CAAA;IAClB,cAAc,CAAC,EAAE;QAAC,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAAA;KAAC,CAAA;IACzC,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAA;IACrC,UAAU,CAAC,EAAE,OAAO,CAAA;IACpB,KAAK,CAAC,EAAE,OAAO,CAAA;CAChB"}
1
+ {"version":3,"file":"ContractContextBuilder.d.ts","sourceRoot":"","sources":["../../src/context/ContractContextBuilder.js"],"names":[],"mappings":"AAMA;;;;;;GAMG;AAEH;;;GAGG;AAEH;;;;GAIG;AAEH;;;;;;;;;GASG;AAEH;;;GAGG;AACH,oCAHiD,EAAE,SAAtC;IAAE,CAAC,IAAI,EAAE,MAAM,GAAG,eAAe,CAAA;CAAE,EACF,EAAE,SAAnC;IAAE,CAAC,IAAI,EAAE,MAAM,GAAG,YAAY,CAAA;CAAE;IA2BzC;;OAEG;IACH,gBAFa,sBAAsB,CAAC,EAAE,EAAE,EAAE,CAAC,CAI1C;IAfD;;;;OAIG;IACH,sBAGC;IAtBD;;;;OAIG;IACH,4BAAU;IAEV;;;;OAIG;IACH,yBAAO;IAmBP;;;;;;;OAOG;IACH,KAP+B,CAAC,SAAlB,eAAgB,aACnB,CAAC,GACC,sBAAsB,CAC9B,EAAE,GAAG,GAAE,CAAe,IAAV,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,GAAC,EAC3B,EAAE,GAAG,mBAAmB,CAAC,CAAC,CAAC,CAC5B,CAeH;IAED;;;;;;;OAOG;IACH,WAP4B,CAAC,SAAf,YAAa,KAChB,CAAC,GACC,sBAAsB,CAC9B,EAAE,EACF,EAAE,GAAG,GAAE,CAAe,IAAV,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,GAAC,CAC5B,CAUH;IAED;;;OAGG;IACH,aAHW,yBAAyB,GACvB,eAAe,CAAC,EAAE,EAAE,EAAE,CAAC,CAsHnC;CACJ;uBAnOY,OAAO,mBAAmB,EAAE,QAAQ;yBACpC,OAAO,kBAAkB,EAAE,UAAU;2BACrC,OAAO,4BAA4B,EAAE,YAAY;8BACjD,OAAO,+BAA+B,EAAE,eAAe;0BACvD,OAAO,sBAAsB,EAAE,WAAW;gCAIxB,CAAC,SAAlB,eAAgB,IACjB,OAAO,+BAA+B,EAAE,mBAAmB,CAAC,CAAC,CAAC;4BAI1B,EAAE,SAAtC;IAAE,CAAC,IAAI,EAAE,MAAM,GAAG,eAAe,CAAA;CAAE,EACF,EAAE,SAAnC;IAAE,CAAC,IAAI,EAAE,MAAM,GAAG,YAAY,CAAA;CAAE,IAChC,OAAO,sBAAsB,EAAE,eAAe,CAAC,EAAE,EAAE,EAAE,CAAC;;;;wCAKtD;IACR,SAAS,EAAE,OAAO,CAAA;IAClB,cAAc,CAAC,EAAE;QAAC,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAAA;KAAC,CAAA;IACzC,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAA;IACrC,UAAU,CAAC,EAAE,OAAO,CAAA;IACpB,KAAK,CAAC,EAAE,OAAO,CAAA;CAChB"}
@@ -1,131 +1,93 @@
1
1
  export const contractContextCache: ContractContextCache;
2
- export type PlutusVersion = import("@helios-lang/uplc").PlutusVersion;
2
+ export type UplcData = import("@helios-lang/uplc").UplcData;
3
3
  export type UplcProgram = import("@helios-lang/uplc").UplcProgram;
4
- export type UplcProgramV1I = import("@helios-lang/uplc").UplcProgramV1I;
5
- export type UplcProgramV2I = import("@helios-lang/uplc").UplcProgramV2I;
6
- export type UplcSourceMapJsonSafe = import("@helios-lang/uplc").UplcSourceMapJsonSafe;
7
- export type CastConfig = import("../cast/index.js").CastConfig;
8
- export type TypeSchema = import("../codegen/index.js").TypeSchema;
9
- export type AnyContractValidatorContext = import("./ContractContext.js").AnyContractValidatorContext;
10
- export type CacheEntry = {
11
- debug?: boolean;
12
- validators: {
13
- [name: string]: AnyContractValidatorContext;
14
- };
15
- userFuncs: {
16
- [name: string]: UplcProgram;
17
- };
18
- };
19
- export type CacheEntryValidatorsJson = {
20
- [name: string]: {
21
- purpose: "minting" | "spending" | "staking" | "mixed";
22
- bytes: number[];
23
- unoptimizedCborHex?: string;
24
- unoptimizedIr?: string;
25
- unoptimizedSourceMap?: UplcSourceMapJsonSafe;
26
- optimizedCborHex: string;
27
- optimizedIr?: string;
28
- optimizedSourceMap?: UplcSourceMapJsonSafe;
29
- plutusVersion: PlutusVersion;
30
- castConfig: CastConfig;
31
- datum?: TypeSchema;
32
- redeemer: TypeSchema;
33
- };
34
- };
35
- export type CacheEntryUserFuncsJson = {
36
- [name: string]: {
37
- unoptimizedCborHex?: string;
38
- unoptimizedIr?: string;
39
- unoptimizedSourceMap?: UplcSourceMapJsonSafe;
40
- optimizedCborHex: string;
41
- optimizedIr?: string;
42
- optimizedSourceMap?: UplcSourceMapJsonSafe;
43
- plutusVersion: PlutusVersion;
44
- };
45
- };
46
- export type CacheEntryJson = {
47
- debug?: boolean;
48
- validators: CacheEntryValidatorsJson;
49
- userFuncs: CacheEntryUserFuncsJson;
4
+ export type LoadedModule = import("../codegen/LoadedModule.js").LoadedModule;
5
+ export type LoadedValidator = import("../codegen/LoadedValidator.js").LoadedValidator;
6
+ export type CacheEntry = import("./CacheEntry.js").CacheEntry;
7
+ export type CacheEntryJson = import("./CacheEntry.js").CacheEntryJson;
8
+ export type CacheEntryUserFuncsJson = import("./CacheEntry.js").CacheEntryUserFuncsJson;
9
+ export type CacheEntryValidatorsJson = import("./CacheEntry.js").CacheEntryValidatorsJson;
10
+ export type ExplicitCache = {
11
+ has(key: string): boolean;
12
+ get(key: string): JsonSafe;
13
+ set(key: string, entry: JsonSafe): void;
50
14
  };
51
15
  /**
52
- * @typedef {import("@helios-lang/uplc").PlutusVersion} PlutusVersion
16
+ * @typedef {import("@helios-lang/uplc").UplcData} UplcData
53
17
  * @typedef {import("@helios-lang/uplc").UplcProgram} UplcProgram
54
- * @typedef {import("@helios-lang/uplc").UplcProgramV1I} UplcProgramV1I
55
- * @typedef {import("@helios-lang/uplc").UplcProgramV2I} UplcProgramV2I
56
- * @typedef {import("@helios-lang/uplc").UplcSourceMapJsonSafe} UplcSourceMapJsonSafe
57
- * @typedef {import("../cast/index.js").CastConfig} CastConfig
58
- * @typedef {import("../codegen/index.js").TypeSchema} TypeSchema
59
- * @typedef {import("./ContractContext.js").AnyContractValidatorContext} AnyContractValidatorContext
60
- */
61
- /**
62
- * @typedef {{
63
- * debug?: boolean
64
- * validators: {[name: string]: AnyContractValidatorContext}
65
- * userFuncs: {[name: string]: UplcProgram}
66
- * }} CacheEntry
67
- */
68
- /**
69
- * @typedef {{[name: string]: {
70
- * purpose: "minting" | "spending" | "staking" | "mixed"
71
- * bytes: number[]
72
- * unoptimizedCborHex?: string
73
- * unoptimizedIr?: string
74
- * unoptimizedSourceMap?: UplcSourceMapJsonSafe
75
- * optimizedCborHex: string
76
- * optimizedIr?: string
77
- * optimizedSourceMap?: UplcSourceMapJsonSafe
78
- * plutusVersion: PlutusVersion
79
- * castConfig: CastConfig
80
- * datum?: TypeSchema
81
- * redeemer: TypeSchema
82
- * }}} CacheEntryValidatorsJson
83
- */
84
- /**
85
- * @typedef {{[name: string]: {
86
- * unoptimizedCborHex?: string
87
- * unoptimizedIr?: string
88
- * unoptimizedSourceMap?: UplcSourceMapJsonSafe
89
- * optimizedCborHex: string
90
- * optimizedIr?: string
91
- * optimizedSourceMap?: UplcSourceMapJsonSafe
92
- * plutusVersion: PlutusVersion
93
- * }}} CacheEntryUserFuncsJson
18
+ * @typedef {import("../codegen/LoadedModule.js").LoadedModule} LoadedModule
19
+ * @typedef {import("../codegen/LoadedValidator.js").LoadedValidator} LoadedValidator
20
+ * @typedef {import("./CacheEntry.js").CacheEntry} CacheEntry
21
+ * @typedef {import("./CacheEntry.js").CacheEntryJson} CacheEntryJson
22
+ * @typedef {import("./CacheEntry.js").CacheEntryUserFuncsJson} CacheEntryUserFuncsJson
23
+ * @typedef {import("./CacheEntry.js").CacheEntryValidatorsJson} CacheEntryValidatorsJson
94
24
  */
95
25
  /**
96
26
  * @typedef {{
97
- * debug?: boolean
98
- * validators: CacheEntryValidatorsJson
99
- * userFuncs: CacheEntryUserFuncsJson
100
- * }} CacheEntryJson
27
+ * has(key: string): boolean
28
+ * get(key: string): JsonSafe
29
+ * set(key: string, entry: JsonSafe): void
30
+ * }} ExplicitCache
101
31
  */
102
32
  declare class ContractContextCache {
103
33
  /**
34
+ * Used by esbuild-plugin
35
+ * @private
104
36
  * @type {CacheEntry[]}
105
37
  */
106
- cache: CacheEntry[];
38
+ private positionalCache;
39
+ /**
40
+ * Explicitly specified by user by calling setBuildCache()
41
+ * @readwrite
42
+ * @type {Option<ExplicitCache>}
43
+ */
44
+ explicitCache: Option<ExplicitCache>;
107
45
  /**
108
46
  * Load count
47
+ * @private
109
48
  * @type {number}
110
49
  */
111
- i: number;
50
+ private i;
112
51
  /**
52
+ * @private
113
53
  * @type {boolean}
114
54
  */
115
- enabled: boolean;
55
+ private enabled;
116
56
  enable(): void;
57
+ /**
58
+ * Key is only generated if the explicitCache is set
59
+ * @param {{
60
+ * version: string
61
+ * debug: boolean
62
+ * isMainnet: boolean
63
+ * validators: Record<string, LoadedValidator>
64
+ * modules: Record<string, LoadedModule>
65
+ * parameters: Record<string, UplcData>
66
+ * }} props
67
+ * @returns {string}
68
+ */
69
+ genCacheKey(props: {
70
+ version: string;
71
+ debug: boolean;
72
+ isMainnet: boolean;
73
+ validators: Record<string, LoadedValidator>;
74
+ modules: Record<string, LoadedModule>;
75
+ parameters: Record<string, UplcData>;
76
+ }): string;
117
77
  /**
118
78
  * @param {CacheEntryJson[]} json
119
79
  */
120
80
  load(json: CacheEntryJson[]): void;
121
81
  /**
122
- * @param {CacheEntry} hashes
82
+ * @param {string} key - empty string is used to set positional cache (eg. for esbuild-plugn)
83
+ * @param {CacheEntry} entry
123
84
  */
124
- push(hashes: CacheEntry): void;
85
+ set(key: string, entry: CacheEntry): void;
125
86
  /**
87
+ * @param {string} key - empty string is used to access positional cache (eg. for esbuild-plugn)
126
88
  * @returns {Option<CacheEntry>}
127
89
  */
128
- shift(): Option<CacheEntry>;
90
+ get(key: string): Option<CacheEntry>;
129
91
  /**
130
92
  * @return {CacheEntryJson[]}
131
93
  */
@@ -1 +1 @@
1
- {"version":3,"file":"ContractContextCache.d.ts","sourceRoot":"","sources":["../../src/context/ContractContextCache.js"],"names":[],"mappings":"AAgYA,wDAA8D;4BApXjD,OAAO,mBAAmB,EAAE,aAAa;0BACzC,OAAO,mBAAmB,EAAE,WAAW;6BACvC,OAAO,mBAAmB,EAAE,cAAc;6BAC1C,OAAO,mBAAmB,EAAE,cAAc;oCAC1C,OAAO,mBAAmB,EAAE,qBAAqB;yBACjD,OAAO,kBAAkB,EAAE,UAAU;yBACrC,OAAO,qBAAqB,EAAE,UAAU;0CACxC,OAAO,sBAAsB,EAAE,2BAA2B;yBAI1D;IACR,KAAK,CAAC,EAAE,OAAO,CAAA;IACf,UAAU,EAAE;QAAC,CAAC,IAAI,EAAE,MAAM,GAAG,2BAA2B,CAAA;KAAC,CAAA;IACzD,SAAS,EAAE;QAAC,CAAC,IAAI,EAAE,MAAM,GAAG,WAAW,CAAA;KAAC,CAAA;CACzC;uCAIS;IAAC,CAAC,IAAI,EAAE,MAAM,GAAG;QACvB,OAAO,EAAE,SAAS,GAAG,UAAU,GAAG,SAAS,GAAG,OAAO,CAAA;QACrD,KAAK,EAAE,MAAM,EAAE,CAAA;QACf,kBAAkB,CAAC,EAAE,MAAM,CAAA;QAC3B,aAAa,CAAC,EAAE,MAAM,CAAA;QACtB,oBAAoB,CAAC,EAAE,qBAAqB,CAAA;QAC5C,gBAAgB,EAAE,MAAM,CAAA;QACxB,WAAW,CAAC,EAAE,MAAM,CAAA;QACpB,kBAAkB,CAAC,EAAE,qBAAqB,CAAA;QAC1C,aAAa,EAAE,aAAa,CAAA;QAC5B,UAAU,EAAE,UAAU,CAAA;QACtB,KAAK,CAAC,EAAE,UAAU,CAAA;QAClB,QAAQ,EAAE,UAAU,CAAA;KACrB,CAAA;CAAC;sCAIM;IAAC,CAAC,IAAI,EAAE,MAAM,GAAG;QACzB,kBAAkB,CAAC,EAAE,MAAM,CAAA;QAC3B,aAAa,CAAC,EAAE,MAAM,CAAA;QACtB,oBAAoB,CAAC,EAAE,qBAAqB,CAAA;QAC5C,gBAAgB,EAAE,MAAM,CAAA;QACxB,WAAW,CAAC,EAAE,MAAM,CAAA;QACpB,kBAAkB,CAAC,EAAE,qBAAqB,CAAA;QAC1C,aAAa,EAAE,aAAa,CAAA;KAC7B,CAAA;CAAC;6BAIQ;IACR,KAAK,CAAC,EAAE,OAAO,CAAA;IACf,UAAU,EAAE,wBAAwB,CAAA;IACpC,SAAS,EAAE,uBAAuB,CAAA;CACnC;AArDJ;;;;;;;;;GASG;AAEH;;;;;;GAMG;AAEH;;;;;;;;;;;;;;;GAeG;AAEH;;;;;;;;;;GAUG;AAEH;;;;;;GAMG;AAEH;IACI;;OAEG;IACH,OAFU,UAAU,EAAE,CAEjB;IAEL;;;OAGG;IACH,GAFU,MAAM,CAEf;IAED;;OAEG;IACH,SAFU,OAAO,CAEV;IAQP,eAEC;IAED;;OAEG;IACH,WAFW,cAAc,EAAE,QA6I1B;IAED;;OAEG;IACH,aAFW,UAAU,QAMpB;IAED;;OAEG;IACH,SAFa,MAAM,CAAC,UAAU,CAAC,CAY9B;IAED;;OAEG;IACH,UAFY,cAAc,EAAE,CAsH3B;CACJ"}
1
+ {"version":3,"file":"ContractContextCache.d.ts","sourceRoot":"","sources":["../../src/context/ContractContextCache.js"],"names":[],"mappings":"AA0JA,wDAA8D;uBApJjD,OAAO,mBAAmB,EAAE,QAAQ;0BACpC,OAAO,mBAAmB,EAAE,WAAW;2BACvC,OAAO,4BAA4B,EAAE,YAAY;8BACjD,OAAO,+BAA+B,EAAE,eAAe;yBACvD,OAAO,iBAAiB,EAAE,UAAU;6BACpC,OAAO,iBAAiB,EAAE,cAAc;sCACxC,OAAO,iBAAiB,EAAE,uBAAuB;uCACjD,OAAO,iBAAiB,EAAE,wBAAwB;4BAIlD;IACR,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAA;IACzB,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,QAAQ,CAAA;IAC1B,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,QAAQ,GAAG,IAAI,CAAA;CACxC;AAhBJ;;;;;;;;;GASG;AAEH;;;;;;GAMG;AAEH;IACI;;;;OAIG;IACH,wBAAe;IAEf;;;;OAIG;IACH,eAFU,MAAM,CAAC,aAAa,CAAC,CAElB;IAEb;;;;OAIG;IACH,UAAC;IAED;;;OAGG;IACH,gBAAO;IAQP,eAEC;IAED;;;;;;;;;;;OAWG;IACH,mBAVW;QACN,OAAO,EAAE,MAAM,CAAA;QACf,KAAK,EAAE,OAAO,CAAA;QACd,SAAS,EAAE,OAAO,CAAA;QAClB,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC,CAAA;QAC3C,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,YAAY,CAAC,CAAA;QACrC,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAA;KACrC,GACS,MAAM,CA0BlB;IAED;;OAEG;IACH,WAFW,cAAc,EAAE,QAI1B;IAED;;;OAGG;IACH,SAHW,MAAM,SACN,UAAU,QAQpB;IAED;;;OAGG;IACH,SAHW,MAAM,GACJ,MAAM,CAAC,UAAU,CAAC,CAuB9B;IAED;;OAEG;IACH,UAFY,cAAc,EAAE,CAI3B;CACJ"}
@@ -0,0 +1,2 @@
1
+ export type ExplicitCache = import("./ContractContextCache.js").ExplicitCache;
2
+ //# sourceMappingURL=set-fs-build-cache.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"set-fs-build-cache.d.ts","sourceRoot":"","sources":["../../src/context/set-fs-build-cache.js"],"names":[],"mappings":"4BAGa,OAAO,2BAA2B,EAAE,aAAa"}
package/types/index.d.ts CHANGED
@@ -1,5 +1,7 @@
1
1
  export * from "./cast/index.js";
2
2
  export * from "./context/index.js";
3
3
  export { LoadedScriptsWriter } from "./codegen/LoadedScriptsWriter.js";
4
+ export type LoadedValidator = import("./codegen/index.js").LoadedValidator;
5
+ export type LoadedModule = import("./codegen/index.js").LoadedModule;
4
6
  export { typeCheckFiles, typeCheckScripts, loadCompilerLib } from "./compiler/ops.js";
5
7
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.js"],"names":[],"mappings":""}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.js"],"names":[],"mappings":";;;8BAOa,OAAO,oBAAoB,EAAE,eAAe;2BAC5C,OAAO,oBAAoB,EAAE,YAAY"}