@helios-lang/contract-utils 0.2.72 → 0.2.73

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,6 +1,6 @@
1
1
  {
2
2
  "name": "@helios-lang/contract-utils",
3
- "version": "0.2.72",
3
+ "version": "0.2.73",
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",
@@ -28,6 +28,7 @@
28
28
  "@helios-lang/cli-utils": "^0.1.10",
29
29
  "@helios-lang/codec-utils": "^0.2.1",
30
30
  "@helios-lang/compiler-utils": "^0.2.1",
31
+ "@helios-lang/crypto": "0.1.17",
31
32
  "@helios-lang/ledger": "^0.5.8",
32
33
  "@helios-lang/type-utils": "^0.1.25",
33
34
  "@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,293 +61,184 @@ 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
- }
151
+ return this.positionalCache.map(cacheEntryToJsonSafe)
152
+ }
153
+ }
348
154
 
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
- }
155
+ export const contractContextCache = new ContractContextCache()
375
156
 
376
- return {
377
- debug: entry.debug ?? false,
378
- validators: resValidators,
379
- userFuncs: resUserFuncs
380
- }
381
- })
157
+ /**
158
+ * @typedef {"fs"} BuildCacheKind
159
+ */
160
+
161
+ /**
162
+ * @param {BuildCacheKind} kind
163
+ */
164
+ export function setBuildCache(kind) {
165
+ if (kind === "fs") {
166
+ contractContextCache.explicitCache = new FileSystemCache()
167
+ } else {
168
+ throw new Error("invalid build cache props")
382
169
  }
383
170
  }
384
171
 
385
- export const contractContextCache = new ContractContextCache()
172
+ // uses same storage strategy as esbuild-plugin
173
+ /**
174
+ * @implements {ExplicitCache}
175
+ */
176
+ class FileSystemCache {
177
+ /**
178
+ * @private
179
+ * @type {typeof import("node:fs")}
180
+ */
181
+ fs
182
+
183
+ /**
184
+ * @private
185
+ * @type {typeof import("node:os")}
186
+ */
187
+ os
188
+
189
+ /**
190
+ * @private
191
+ * @type {typeof import("node:path")}
192
+ */
193
+ path
194
+
195
+ /**
196
+ * @private
197
+ * @type {string}
198
+ */
199
+ cacheDir
200
+
201
+ constructor() {
202
+ this.fs = require("node:fs")
203
+ this.os = require("node:os")
204
+ this.path = require("node:path")
205
+ this.cacheDir = this.path.join(this.os.tmpdir(), "helios-cache")
206
+
207
+ if (!this.fs.existsSync(this.cacheDir)) {
208
+ this.fs.mkdirSync(this.cacheDir, {
209
+ recursive: true
210
+ })
211
+ }
212
+ }
213
+
214
+ /**
215
+ * @private
216
+ * @param {string} key
217
+ */
218
+ genPath(key) {
219
+ return this.path.join(this.cacheDir, key + ".json")
220
+ }
221
+
222
+ /**
223
+ * @param {string} key
224
+ */
225
+ has(key) {
226
+ return this.fs.existsSync(this.genPath(key))
227
+ }
228
+
229
+ /**
230
+ * @param {string} key
231
+ * @returns {JsonSafe}
232
+ */
233
+ get(key) {
234
+ return JSON.parse(this.fs.readFileSync(this.genPath(key)).toString())
235
+ }
236
+
237
+ /**
238
+ * @param {string} key
239
+ * @param {JsonSafe} obj
240
+ */
241
+ set(key, obj) {
242
+ this.fs.writeFileSync(this.genPath(key), JSON.stringify(obj))
243
+ }
244
+ }
@@ -1,5 +1,5 @@
1
1
  export { ContractContextBuilder } from "./ContractContextBuilder.js"
2
- export { contractContextCache } from "./ContractContextCache.js"
2
+ export { contractContextCache, setBuildCache } from "./ContractContextCache.js"
3
3
 
4
4
  /**
5
5
  * @template {{[name: string]: import("../codegen/index.js").LoadedValidator}} Vs
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,101 @@
1
- export const contractContextCache: ContractContextCache;
2
- export type PlutusVersion = import("@helios-lang/uplc").PlutusVersion;
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;
50
- };
51
- /**
52
- * @typedef {import("@helios-lang/uplc").PlutusVersion} PlutusVersion
53
- * @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
1
  /**
62
- * @typedef {{
63
- * debug?: boolean
64
- * validators: {[name: string]: AnyContractValidatorContext}
65
- * userFuncs: {[name: string]: UplcProgram}
66
- * }} CacheEntry
2
+ * @typedef {"fs"} BuildCacheKind
67
3
  */
68
4
  /**
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
5
+ * @param {BuildCacheKind} kind
83
6
  */
7
+ export function setBuildCache(kind: BuildCacheKind): void;
8
+ export const contractContextCache: ContractContextCache;
9
+ export type BuildCacheKind = "fs";
10
+ export type UplcData = import("@helios-lang/uplc").UplcData;
11
+ export type UplcProgram = import("@helios-lang/uplc").UplcProgram;
12
+ export type LoadedModule = import("../codegen/LoadedModule.js").LoadedModule;
13
+ export type LoadedValidator = import("../codegen/LoadedValidator.js").LoadedValidator;
14
+ export type CacheEntry = import("./CacheEntry.js").CacheEntry;
15
+ export type CacheEntryJson = import("./CacheEntry.js").CacheEntryJson;
16
+ export type CacheEntryUserFuncsJson = import("./CacheEntry.js").CacheEntryUserFuncsJson;
17
+ export type CacheEntryValidatorsJson = import("./CacheEntry.js").CacheEntryValidatorsJson;
18
+ export type ExplicitCache = {
19
+ has(key: string): boolean;
20
+ get(key: string): JsonSafe;
21
+ set(key: string, entry: JsonSafe): void;
22
+ };
84
23
  /**
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
24
+ * @typedef {import("@helios-lang/uplc").UplcData} UplcData
25
+ * @typedef {import("@helios-lang/uplc").UplcProgram} UplcProgram
26
+ * @typedef {import("../codegen/LoadedModule.js").LoadedModule} LoadedModule
27
+ * @typedef {import("../codegen/LoadedValidator.js").LoadedValidator} LoadedValidator
28
+ * @typedef {import("./CacheEntry.js").CacheEntry} CacheEntry
29
+ * @typedef {import("./CacheEntry.js").CacheEntryJson} CacheEntryJson
30
+ * @typedef {import("./CacheEntry.js").CacheEntryUserFuncsJson} CacheEntryUserFuncsJson
31
+ * @typedef {import("./CacheEntry.js").CacheEntryValidatorsJson} CacheEntryValidatorsJson
94
32
  */
95
33
  /**
96
34
  * @typedef {{
97
- * debug?: boolean
98
- * validators: CacheEntryValidatorsJson
99
- * userFuncs: CacheEntryUserFuncsJson
100
- * }} CacheEntryJson
35
+ * has(key: string): boolean
36
+ * get(key: string): JsonSafe
37
+ * set(key: string, entry: JsonSafe): void
38
+ * }} ExplicitCache
101
39
  */
102
40
  declare class ContractContextCache {
103
41
  /**
42
+ * Used by esbuild-plugin
43
+ * @private
104
44
  * @type {CacheEntry[]}
105
45
  */
106
- cache: CacheEntry[];
46
+ private positionalCache;
47
+ /**
48
+ * Explicitly specified by user by calling setBuildCache()
49
+ * @readwrite
50
+ * @type {Option<ExplicitCache>}
51
+ */
52
+ explicitCache: Option<ExplicitCache>;
107
53
  /**
108
54
  * Load count
55
+ * @private
109
56
  * @type {number}
110
57
  */
111
- i: number;
58
+ private i;
112
59
  /**
60
+ * @private
113
61
  * @type {boolean}
114
62
  */
115
- enabled: boolean;
63
+ private enabled;
116
64
  enable(): void;
65
+ /**
66
+ * Key is only generated if the explicitCache is set
67
+ * @param {{
68
+ * version: string
69
+ * debug: boolean
70
+ * isMainnet: boolean
71
+ * validators: Record<string, LoadedValidator>
72
+ * modules: Record<string, LoadedModule>
73
+ * parameters: Record<string, UplcData>
74
+ * }} props
75
+ * @returns {string}
76
+ */
77
+ genCacheKey(props: {
78
+ version: string;
79
+ debug: boolean;
80
+ isMainnet: boolean;
81
+ validators: Record<string, LoadedValidator>;
82
+ modules: Record<string, LoadedModule>;
83
+ parameters: Record<string, UplcData>;
84
+ }): string;
117
85
  /**
118
86
  * @param {CacheEntryJson[]} json
119
87
  */
120
88
  load(json: CacheEntryJson[]): void;
121
89
  /**
122
- * @param {CacheEntry} hashes
90
+ * @param {string} key - empty string is used to set positional cache (eg. for esbuild-plugn)
91
+ * @param {CacheEntry} entry
123
92
  */
124
- push(hashes: CacheEntry): void;
93
+ set(key: string, entry: CacheEntry): void;
125
94
  /**
95
+ * @param {string} key - empty string is used to access positional cache (eg. for esbuild-plugn)
126
96
  * @returns {Option<CacheEntry>}
127
97
  */
128
- shift(): Option<CacheEntry>;
98
+ get(key: string): Option<CacheEntry>;
129
99
  /**
130
100
  * @return {CacheEntryJson[]}
131
101
  */
@@ -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":"AA4JA;;GAEG;AAEH;;GAEG;AACH,oCAFW,cAAc,QAQxB;AAfD,wDAA8D;6BAGjD,IAAI;uBAvJJ,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"}
@@ -1,8 +1,8 @@
1
1
  export { ContractContextBuilder } from "./ContractContextBuilder.js";
2
- export { contractContextCache } from "./ContractContextCache.js";
3
2
  export type ContractContext<Vs extends {
4
3
  [name: string]: import("../codegen/index.js").LoadedValidator;
5
4
  }, Ms extends {
6
5
  [name: string]: import("../codegen/index.js").LoadedModule;
7
6
  }> = import("./ContractContext.js").ContractContext<Vs, Ms>;
7
+ export { contractContextCache, setBuildCache } from "./ContractContextCache.js";
8
8
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/context/index.js"],"names":[],"mappings":";;4BAI+E,EAAE,SAApE;IAAE,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,qBAAqB,EAAE,eAAe,CAAA;CAAE,EACF,EAAE,SAAjE;IAAE,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,qBAAqB,EAAE,YAAY,CAAA;CAAE,IAC9D,OAAO,sBAAsB,EAAE,eAAe,CAAC,EAAE,EAAE,EAAE,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/context/index.js"],"names":[],"mappings":";4BAI+E,EAAE,SAApE;IAAE,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,qBAAqB,EAAE,eAAe,CAAA;CAAE,EACF,EAAE,SAAjE;IAAE,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,qBAAqB,EAAE,YAAY,CAAA;CAAE,IAC9D,OAAO,sBAAsB,EAAE,eAAe,CAAC,EAAE,EAAE,EAAE,CAAC"}
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"}