@@ -213,10 +213,10 @@ LiquidSpec.compile do |ctx, source, options|
213213 ctx[:template ] = MyLiquid ::Template .parse(source, ** options)
214214end
215215
216- # Render the template compiled immediately above .
216+ # Render the template stored by compile or load_artifact .
217217LiquidSpec .render do |ctx , assigns , options |
218218 # assigns = variables hash
219- # options includes: :registers, :strict_errors, :error_mode
219+ # options includes: :registers, :strict_errors, :error_mode, :exception_renderer
220220 ctx[:template ].render(assigns, ** options)
221221end
222222```
@@ -248,28 +248,54 @@ liquid-spec run my_adapter.rb --json --list-passed > results.json
248248
249249### Optional: compiled-artifact protocol
250250
251- If your implementation can persist a compiled template as a string (e.g. an
252- ISeq/bytecode blob stored in memcache or a database) and load it back in a
253- process that never saw the source, declare both hooks:
251+ Some Liquid implementations compile source once, store executable bytecode or
252+ an equivalent compiled representation in a shared cache, and load those bytes
253+ in application processes that never receive the source. ` compile ` and ` render `
254+ alone cannot measure that important production path: parsing again is not an
255+ artifact-cache hit, while repeatedly rendering a resident template omits the
256+ load and first-use costs.
257+
258+ If your implementation has such a persistent compiled format, declare both
259+ hooks:
254260
255261``` ruby
256- # Serialize the compiled template (ctx[:template]) into a String
262+ # Called immediately after LiquidSpec.compile, before the template is rendered.
263+ # Return the exact binary String you would put in memcache, a database, etc.
257264LiquidSpec .dump_artifact do |ctx |
258265 ctx[:template ].to_artifact
259266end
260267
261- # Load an artifact string back into a renderable template
262- LiquidSpec .load_artifact do |ctx , blob , options |
263- ctx[:template ] = MyLiquid ::Artifact .load (blob)
268+ # Called in a runtime-loaded, template-cold fork that has the bytes but no source.
269+ # Restore all adapter state expected by the regular LiquidSpec.render hook.
270+ LiquidSpec .load_artifact do |ctx , bytes , _options |
271+ ctx[:template ] = MyLiquid ::Artifact .load (bytes)
264272end
265273```
266274
267- The core ` liquid-spec bench ADAPTER ` command then adds an artifact stage per spec: it
268- verifies that the dump → load → render roundtrip reproduces the compiled template's output,
269- and measures payload bytes, cold artifact load time, first render after a
270- cold load, and steady-state load time/allocations (the compile-once →
271- persist → cold load+render production path). Adapters without these hooks
272- are unaffected.
275+ The contract is deliberately production-oriented:
276+
277+ 1 . ` dump_artifact ` receives the state produced by ` compile ` and must return a
278+ binary-safe ` String ` . It is invoked before any validation render, because
279+ rendering is allowed to mutate template runtime state.
280+ 2 . The returned bytes must contain all immutable compile-time information needed
281+ to load the template without its source. Do not capture assigns, observed
282+ values, request objects, or render-time object shapes.
283+ 3 . ` load_artifact ` must leave ` ctx ` in the same renderable state that ` compile `
284+ would. The source is unavailable. Its third argument is the runtime options
285+ Hash that the following ` render ` hook will receive; most loaders ignore it.
286+ 4 . Assigns, registers, and runtime filesystems are still supplied to the normal
287+ ` render ` hook for every call; they are not part of the artifact.
288+
289+ With both hooks, ` --bench ` validates the dump → load → render roundtrip, reports
290+ raw artifact bytes and steady-state load diagnostics, and measures the atomic
291+ artifact-load + first-render workflow in 30 forked children. The parent runtime
292+ is loaded but has never seen the benchmark template, and fork/IPC work is outside
293+ the timer. This models a shared artifact fetched into memory in another process.
294+
295+ ` --bench ` warns when either hook is missing because artifact size and
296+ load+first-render results will be omitted. Implementations without a persistent
297+ compiled format may leave the hooks absent; the warning documents that the
298+ benchmark is then limited to source compile and resident render paths.
273299
274300### Optional: local suites
275301
0 commit comments