Skip to content
This repository was archived by the owner on Mar 13, 2025. It is now read-only.

Commit 974c7c2

Browse files
committed
Bump versions to 2.9.0, update CHANGELOG.md and docs
1 parent a98e0f5 commit 974c7c2

File tree

34 files changed

+525
-412
lines changed

34 files changed

+525
-412
lines changed

docs/src/content/get-started/cli.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -219,6 +219,17 @@ Specifying a script is optional when `--repl` is enabled, but may be required if
219219
you're using Durable Objects. If you're using an ES module format worker,
220220
bindings will be accessible via the `env` global variable.
221221

222+
The REPL can be configured using environment variables similar to
223+
[Node.js](https://nodejs.org/api/repl.html#environment-variable-options):
224+
225+
- `MINIFLARE_REPL_HISTORY`: path to save REPL history to. Setting this to an
226+
empty string disables persistent REPL history. Defaults to
227+
`~/.mf_repl_history`.
228+
- `MINIFLARE_REPL_HISTORY_SIZE`: number of history lines to save if persistent
229+
REPL history is enabled. Defaults to `1000`.
230+
- `MINIFLARE_REPL_MODE`: either `sloppy` or `strict`. Defaults to `sloppy`
231+
allowing non-strict code to run.
232+
222233
```sh
223234
$ miniflare --repl --kv TEST_NAMESPACE
224235
> await new HTMLRewriter().on("p", {

docs/src/content/testing/jest.md

Lines changed: 54 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -84,10 +84,10 @@ $ NODE_OPTIONS=--experimental-vm-modules npx jest
8484
## Isolated Storage
8585

8686
The Miniflare environment will use isolated storage for KV namespaces, caches,
87-
and Durable Objects in each test. This essentially means any changes you make in
88-
a test or `describe`-block are automatically undone afterwards. The isolated
89-
storage is copied from the parent `describe`-block, allowing you to seed data in
90-
`beforeAll` hooks.
87+
Durable Objects and D1 databases in each test. This essentially means any
88+
changes you make in a test or `describe`-block are automatically undone
89+
afterwards. The isolated storage is copied from the parent `describe`-block,
90+
allowing you to seed data in `beforeAll` hooks.
9191

9292
As an example, consider the following tests:
9393

@@ -188,7 +188,7 @@ export class TestObject {
188188
}
189189

190190
async fetch() {
191-
const count = (await this.storage.get("count")) + 1;
191+
const count = ((await this.storage.get("count")) ?? 0) + 1;
192192
this.storage.put("count", count);
193193
return new Response(count.toString());
194194
}
@@ -264,6 +264,55 @@ test("flushes alarms", async () => {
264264
});
265265
```
266266
267+
### Constructing Durable Objects Directly
268+
269+
Alternatively, you can construct instances of your Durable Object using
270+
`DurableObjectState`s returned by the `getMiniflareDurableObjectState()` global
271+
function. This allows you to call instance methods and access ephemeral state
272+
directly. Wrapping calls to instance methods with
273+
`runWithMiniflareDurableObjectGates()` will close the Durable Object's input
274+
gate, and wait for the output gate to open before resolving. Make sure to use
275+
this when calling your `fetch()` method.
276+
277+
```js
278+
---
279+
filename: test / index.spec.js
280+
---
281+
import { TestObject } from "../src/index.mjs";
282+
283+
test("increments count", async () => {
284+
const env = getMiniflareBindings();
285+
// Use standard Durable Object bindings to generate IDs
286+
const id = env.TEST_OBJECT.newUniqueId();
287+
288+
// Get DurableObjectState, and seed Durable Object storage
289+
// (isolated storage rules from above also apply)
290+
const state = await getMiniflareDurableObjectState(id);
291+
await state.storage.put("count", 3);
292+
293+
// Construct object directly
294+
const object = new TestObject(state, env);
295+
296+
// Concurrently increment the count twice. Wrapping `object.fetch`
297+
// calls with `runWithMiniflareDurableObjectGates(state, ...)`
298+
// closes `object`'s input gate when fetching, preventing race
299+
// conditions.
300+
const [res1, res2] = await Promise.all([
301+
runWithMiniflareDurableObjectGates(state, () => {
302+
return object.fetch(new Request("http://localhost/"));
303+
}),
304+
runWithMiniflareDurableObjectGates(state, () => {
305+
return object.fetch(new Request("http://localhost/"));
306+
}),
307+
]);
308+
expect(await res1.text()).toBe("4");
309+
expect(await res2.text()).toBe("5");
310+
311+
// Check storage updated twice
312+
expect(await state.storage.get("count")).toBe(5);
313+
});
314+
```
315+
267316
## Mocking Outbound `fetch` Requests
268317
269318
Miniflare allows you to substitute custom `Response`s for `fetch()` calls using

docs/src/content/testing/vitest.md

Lines changed: 56 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -87,10 +87,10 @@ $ NODE_OPTIONS=--experimental-vm-modules npx vitest run
8787
## Isolated Storage
8888

8989
The Miniflare environment will use isolated storage for KV namespaces, caches,
90-
and Durable Objects in each test. This essentially means any changes you make in
91-
a test or `describe`-block are automatically undone afterwards. The isolated
92-
storage is copied from the parent `describe`-block, allowing you to seed data in
93-
`beforeAll` hooks.
90+
Durable Objects and D1 databases in each test. This essentially means any
91+
changes you make in a test or `describe`-block are automatically undone
92+
afterwards. The isolated storage is copied from the parent `describe`-block,
93+
allowing you to seed data in `beforeAll` hooks.
9494

9595
<Aside type="warning" header="Warning">
9696

@@ -294,6 +294,58 @@ test("flushes alarms", async () => {
294294
});
295295
```
296296
297+
### Constructing Durable Objects Directly
298+
299+
Alternatively, you can construct instances of your Durable Object using
300+
`DurableObjectState`s returned by the `getMiniflareDurableObjectState()` global
301+
function. This allows you to call instance methods and access ephemeral state
302+
directly. Wrapping calls to instance methods with
303+
`runWithMiniflareDurableObjectGates()` will close the Durable Object's input
304+
gate, and wait for the output gate to open before resolving. Make sure to use
305+
this when calling your `fetch()` method.
306+
307+
```js
308+
---
309+
filename: test / index.spec.js
310+
---
311+
import { expect, test } from "vitest";
312+
const describe = setupMiniflareIsolatedStorage();
313+
314+
import { TestObject } from "../src/index.mjs";
315+
316+
test("increments count", async () => {
317+
const env = getMiniflareBindings();
318+
// Use standard Durable Object bindings to generate IDs
319+
const id = env.TEST_OBJECT.newUniqueId();
320+
321+
// Get DurableObjectState, and seed Durable Object storage
322+
// (isolated storage rules from above also apply)
323+
const state = await getMiniflareDurableObjectState(id);
324+
await state.storage.put("count", 3);
325+
326+
// Construct object directly
327+
const object = new TestObject(state, env);
328+
329+
// Concurrently increment the count twice. Wrapping `object.fetch`
330+
// calls with `runWithMiniflareDurableObjectGates(state, ...)`
331+
// closes `object`'s input gate when fetching, preventing race
332+
// conditions.
333+
const [res1, res2] = await Promise.all([
334+
runWithMiniflareDurableObjectGates(state, () => {
335+
return object.fetch(new Request("http://localhost/"));
336+
}),
337+
runWithMiniflareDurableObjectGates(state, () => {
338+
return object.fetch(new Request("http://localhost/"));
339+
}),
340+
]);
341+
expect(await res1.text()).toBe("4");
342+
expect(await res2.text()).toBe("5");
343+
344+
// Check storage updated twice
345+
expect(await state.storage.get("count")).toBe(5);
346+
});
347+
```
348+
297349
## Mocking Outbound `fetch` Requests
298350
299351
Miniflare allows you to substitute custom `Response`s for `fetch()` calls using

0 commit comments

Comments
 (0)