Skip to content

Commit

Permalink
initial draft copied from #7087
Browse files Browse the repository at this point in the history
  • Loading branch information
edmundhung committed Nov 19, 2024
1 parent edec415 commit a6f766b
Show file tree
Hide file tree
Showing 4 changed files with 54 additions and 120 deletions.
147 changes: 27 additions & 120 deletions packages/wrangler/src/api/integrations/platform/index.ts
Original file line number Diff line number Diff line change
@@ -1,24 +1,20 @@
import { kCurrentWorker, Miniflare } from "miniflare";
import { kCurrentWorker } from "miniflare";
import { processAssetsArg } from "../../../assets";
import { readConfig } from "../../../config";
import { DEFAULT_MODULE_RULES } from "../../../deployment-bundle/rules";
import { getBindings } from "../../../dev";
import { getBoundRegisteredWorkers } from "../../../dev-registry";
import { getVarsForDev } from "../../../dev/dev-vars";
import {
buildAssetOptions,
buildMiniflareBindingOptions,
buildSitesOptions,
} from "../../../dev/miniflare";
import { getClassNamesWhichUseSQLite } from "../../../dev/validate-dev-props";
import { run } from "../../../experimental-flags";
import { getLegacyAssetPaths, getSiteAssetPaths } from "../../../sites";
import { startWorker } from "../../startDevWorker";
import { CacheStorage } from "./caches";
import { ExecutionContext } from "./executionContext";
import { getServiceBindings } from "./services";
import type { Config } from "../../../config";
import type { IncomingRequestCfProperties } from "@cloudflare/workers-types/experimental";
import type { MiniflareOptions, ModuleRule, WorkerOptions } from "miniflare";
import type { ModuleRule, WorkerOptions } from "miniflare";

/**
* Options for the `getPlatformProxy` utility
Expand Down Expand Up @@ -101,130 +97,41 @@ export async function getPlatformProxy<
>(
options: GetPlatformProxyOptions = {}
): Promise<PlatformProxy<Env, CfProperties>> {
const env = options.environment;

const rawConfig = readConfig(options.configPath, {
experimentalJsonConfig: options.experimentalJsonConfig,
env,
});

const miniflareOptions = await run(
{
FILE_BASED_REGISTRY: Boolean(options.experimentalRegistry ?? true),
JSON_CONFIG_FILE: Boolean(options.experimentalJsonConfig),
// TODO: Allow skipping custom build

const worker = await startWorker({
config: options.configPath,
env: options.environment,
dev: {
inspector: {
port: 0,
},
server: {
port: 0,
},
logLevel: "none",
liveReload: false,
watch: false,
persist:
typeof options.persist === "object"
? options.persist.path
: options.persist
? ".wrangler/state/v3"
: undefined,
},
() => getMiniflareOptionsFromConfig(rawConfig, env, options)
);

const mf = new Miniflare({
script: "",
modules: true,
...(miniflareOptions as Record<string, unknown>),
});

const mf = await worker.getLocalMiniflareInstance();
const bindings: Env = await mf.getBindings();

const vars = getVarsForDev(rawConfig, env);

const cf = await mf.getCf();
deepFreeze(cf);

return {
env: {
...vars,
...bindings,
},
env: bindings,
cf: cf as CfProperties,
ctx: new ExecutionContext(),
caches: new CacheStorage(),
dispose: () => mf.dispose(),
};
}

async function getMiniflareOptionsFromConfig(
rawConfig: Config,
env: string | undefined,
options: GetPlatformProxyOptions
): Promise<Partial<MiniflareOptions>> {
const bindings = getBindings(rawConfig, env, true, {});

const workerDefinitions = await getBoundRegisteredWorkers({
name: rawConfig.name,
services: bindings.services,
durableObjects: rawConfig["durable_objects"],
});

const { bindingOptions, externalWorkers } = buildMiniflareBindingOptions({
name: undefined,
bindings,
workerDefinitions,
queueConsumers: undefined,
services: rawConfig.services,
serviceBindings: {},
migrations: rawConfig.migrations,
});

const persistOptions = getMiniflarePersistOptions(options.persist);

const serviceBindings = await getServiceBindings(bindings.services);

const miniflareOptions: MiniflareOptions = {
workers: [
{
script: "",
modules: true,
...bindingOptions,
serviceBindings: {
...serviceBindings,
...bindingOptions.serviceBindings,
},
},
...externalWorkers,
],
...persistOptions,
};

return miniflareOptions;
}

/**
* Get the persist option properties to pass to miniflare
*
* @param persist The user provided persistence option
* @returns an object containing the properties to pass to miniflare
*/
function getMiniflarePersistOptions(
persist: GetPlatformProxyOptions["persist"]
): Pick<
MiniflareOptions,
| "kvPersist"
| "durableObjectsPersist"
| "r2Persist"
| "d1Persist"
| "workflowsPersist"
> {
if (persist === false) {
// the user explicitly asked for no persistance
return {
kvPersist: false,
durableObjectsPersist: false,
r2Persist: false,
d1Persist: false,
workflowsPersist: false,
};
}

const defaultPersistPath = ".wrangler/state/v3";

const persistPath =
typeof persist === "object" ? persist.path : defaultPersistPath;

return {
kvPersist: `${persistPath}/kv`,
durableObjectsPersist: `${persistPath}/do`,
r2Persist: `${persistPath}/r2`,
d1Persist: `${persistPath}/d1`,
workflowsPersist: `${persistPath}/workflows`,
dispose: () => worker.dispose(),
};
}

Expand Down
11 changes: 11 additions & 0 deletions packages/wrangler/src/api/startDevWorker/DevEnv.ts
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,17 @@ function createWorkerObject(devEnv: DevEnv): Worker {
const w = await proxyWorker.getWorker(this.config.name);
return w.scheduled(...args);
},
async getLocalMiniflareInstance() {
const local = devEnv.runtimes.find(
(ctrl) => ctrl instanceof LocalRuntimeController
);

if (this.config.dev.remote || !local) {
throw new Error("local only");
}

return await local.getMiniflareInstance();
},
async dispose() {
await devEnv.teardown();
},
Expand Down
15 changes: 15 additions & 0 deletions packages/wrangler/src/api/startDevWorker/LocalRuntimeController.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { randomUUID } from "node:crypto";
import events from "node:events";
import { readFile } from "node:fs/promises";
import chalk from "chalk";
import { Miniflare, Mutex } from "miniflare";
Expand Down Expand Up @@ -142,6 +143,20 @@ export class LocalRuntimeController extends RuntimeController {
#mutex = new Mutex();
#mf?: Miniflare;

async getMiniflareInstance() {
if (this.#mf) {
return this.#mf;
}

await events.once(this, "reloadComplete");

if (!this.#mf) {
throw new Error("Miniflare instance is not available after reload");
}

return this.#mf;
}

onBundleStart(_: BundleStartEvent) {
// Ignored in local runtime
}
Expand Down
1 change: 1 addition & 0 deletions packages/wrangler/src/api/startDevWorker/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ export interface Worker {
fetch: DispatchFetch;
scheduled: MiniflareWorker["scheduled"];
queue: MiniflareWorker["queue"];
getLocalMiniflareInstance(): Promise<Miniflare>;
dispose(): Promise<void>;
}

Expand Down

0 comments on commit a6f766b

Please sign in to comment.