@executor-js/plugin-example 0.0.2 → 0.2.1
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/dist/{chunk-FWMQSD3O.js → chunk-M7BJ2IL4.js} +2 -2
- package/dist/chunk-M7BJ2IL4.js.map +1 -0
- package/dist/client.js +2 -6
- package/dist/client.js.map +1 -1
- package/dist/server.d.ts +13 -9
- package/dist/server.js +12 -17
- package/dist/server.js.map +1 -1
- package/dist/shared.d.ts +1 -1
- package/dist/shared.js +1 -1
- package/package.json +10 -10
- package/dist/chunk-FWMQSD3O.js.map +0 -1
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// src/shared.ts
|
|
2
|
-
import { HttpApiEndpoint, HttpApiGroup, Schema } from "@executor-js/sdk";
|
|
2
|
+
import { HttpApiEndpoint, HttpApiGroup, Schema } from "@executor-js/sdk/core";
|
|
3
3
|
var Greeting = Schema.Struct({
|
|
4
4
|
message: Schema.String,
|
|
5
5
|
count: Schema.Number
|
|
@@ -15,4 +15,4 @@ export {
|
|
|
15
15
|
Greeting,
|
|
16
16
|
ExampleApi
|
|
17
17
|
};
|
|
18
|
-
//# sourceMappingURL=chunk-
|
|
18
|
+
//# sourceMappingURL=chunk-M7BJ2IL4.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/shared.ts"],"sourcesContent":["// ---------------------------------------------------------------------------\n// @executor-js/plugin-example/shared\n//\n// Schemas and the HttpApiGroup definition shared between the server and\n// client halves. Both `./server` and `./client` import from here so the\n// frontend's typed reactive client and the backend's handlers see the\n// exact same payload/response/error contracts.\n//\n// No React or Node imports here — server and client both import this.\n// ---------------------------------------------------------------------------\n\nimport { HttpApiEndpoint, HttpApiGroup, Schema } from \"@executor-js/sdk/core\";\n\nexport const Greeting = Schema.Struct({\n message: Schema.String,\n count: Schema.Number,\n});\nexport type Greeting = typeof Greeting.Type;\n\nexport const ExampleApi = HttpApiGroup.make(\"example\").add(\n HttpApiEndpoint.post(\"greet\", \"/greet\", {\n payload: Schema.Struct({ name: Schema.String }),\n success: Greeting,\n }),\n);\n"],"mappings":";AAWA,SAAS,iBAAiB,cAAc,cAAc;AAE/C,IAAM,WAAW,OAAO,OAAO;AAAA,EACpC,SAAS,OAAO;AAAA,EAChB,OAAO,OAAO;AAChB,CAAC;AAGM,IAAM,aAAa,aAAa,KAAK,SAAS,EAAE;AAAA,EACrD,gBAAgB,KAAK,SAAS,UAAU;AAAA,IACtC,SAAS,OAAO,OAAO,EAAE,MAAM,OAAO,OAAO,CAAC;AAAA,IAC9C,SAAS;AAAA,EACX,CAAC;AACH;","names":[]}
|
package/dist/client.js
CHANGED
|
@@ -1,14 +1,10 @@
|
|
|
1
1
|
import {
|
|
2
2
|
ExampleApi
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-M7BJ2IL4.js";
|
|
4
4
|
|
|
5
5
|
// src/client.tsx
|
|
6
6
|
import { useState } from "react";
|
|
7
|
-
import {
|
|
8
|
-
defineClientPlugin,
|
|
9
|
-
createPluginAtomClient,
|
|
10
|
-
useAtomSet
|
|
11
|
-
} from "@executor-js/sdk/client";
|
|
7
|
+
import { defineClientPlugin, createPluginAtomClient, useAtomSet } from "@executor-js/sdk/client";
|
|
12
8
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
13
9
|
var ExampleClient = createPluginAtomClient(ExampleApi);
|
|
14
10
|
var greetAtom = ExampleClient.mutation("example", "greet");
|
package/dist/client.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/client.tsx"],"sourcesContent":["// ---------------------------------------------------------------------------\n// @executor-js/plugin-example/client\n//\n// Frontend half: a single page that calls the plugin's `greet` mutation\n// and renders the response. Demonstrates the typed reactive client\n// pattern — `ExampleClient.mutation(...)` is fully typed against\n// `ExampleApi` from `./shared` with no codegen.\n//\n// Server-only deps (Effect, Node, executor.config) MUST NOT be imported\n// here — the Vite plugin bundles this entry into the frontend.\n// ---------------------------------------------------------------------------\n\nimport { useState } from \"react\";\nimport {
|
|
1
|
+
{"version":3,"sources":["../src/client.tsx"],"sourcesContent":["// ---------------------------------------------------------------------------\n// @executor-js/plugin-example/client\n//\n// Frontend half: a single page that calls the plugin's `greet` mutation\n// and renders the response. Demonstrates the typed reactive client\n// pattern — `ExampleClient.mutation(...)` is fully typed against\n// `ExampleApi` from `./shared` with no codegen.\n//\n// Server-only deps (Effect, Node, executor.config) MUST NOT be imported\n// here — the Vite plugin bundles this entry into the frontend.\n// ---------------------------------------------------------------------------\n\nimport { useState } from \"react\";\nimport { defineClientPlugin, createPluginAtomClient, useAtomSet } from \"@executor-js/sdk/client\";\n\nimport { ExampleApi } from \"./shared\";\n\nconst ExampleClient = createPluginAtomClient(ExampleApi);\n\nconst greetAtom = ExampleClient.mutation(\"example\", \"greet\");\n\nfunction ExamplePage() {\n const [name, setName] = useState(\"world\");\n const [result, setResult] = useState<string>();\n const doGreet = useAtomSet(greetAtom, { mode: \"promise\" });\n\n return (\n <div style={{ maxWidth: 480, margin: \"2rem auto\", padding: \"1rem\" }}>\n <h1 style={{ fontSize: \"1.25rem\", marginBottom: \"1rem\" }}>Example plugin</h1>\n <div style={{ display: \"flex\", gap: 8 }}>\n {/* The example plugin demonstrates the SDK in isolation, so it\n uses raw HTML controls instead of `@executor-js/react`'s\n wrapped components — third-party plugin authors don't have\n to depend on the host's component library. */}\n {/* oxlint-disable-next-line react/forbid-elements */}\n <input\n value={name}\n onChange={(e) => setName(e.target.value)}\n style={{\n flex: 1,\n padding: \"0.5rem 0.75rem\",\n border: \"1px solid #ccc\",\n borderRadius: 6,\n }}\n />\n {/* oxlint-disable-next-line react/forbid-elements */}\n <button\n type=\"button\"\n onClick={async () => {\n // Mutation has no shared state to invalidate — explicit\n // empty `reactivityKeys` documents the intent for the\n // `require-reactivity-keys` rule.\n const g = await doGreet({ payload: { name }, reactivityKeys: [] });\n setResult(`${g.message} (#${g.count})`);\n }}\n style={{\n padding: \"0.5rem 0.75rem\",\n border: \"1px solid #ccc\",\n borderRadius: 6,\n cursor: \"pointer\",\n }}\n >\n Greet\n </button>\n </div>\n {result && (\n <pre style={{ marginTop: \"1rem\", padding: \"0.5rem\", background: \"#f5f5f5\" }}>{result}</pre>\n )}\n </div>\n );\n}\n\nexport default defineClientPlugin({\n id: \"example\" as const,\n pages: [\n {\n path: \"/\",\n component: ExamplePage,\n nav: { label: \"Example\" },\n },\n ],\n});\n"],"mappings":";;;;;AAYA,SAAS,gBAAgB;AACzB,SAAS,oBAAoB,wBAAwB,kBAAkB;AAejE,cACA,YADA;AAXN,IAAM,gBAAgB,uBAAuB,UAAU;AAEvD,IAAM,YAAY,cAAc,SAAS,WAAW,OAAO;AAE3D,SAAS,cAAc;AACrB,QAAM,CAAC,MAAM,OAAO,IAAI,SAAS,OAAO;AACxC,QAAM,CAAC,QAAQ,SAAS,IAAI,SAAiB;AAC7C,QAAM,UAAU,WAAW,WAAW,EAAE,MAAM,UAAU,CAAC;AAEzD,SACE,qBAAC,SAAI,OAAO,EAAE,UAAU,KAAK,QAAQ,aAAa,SAAS,OAAO,GAChE;AAAA,wBAAC,QAAG,OAAO,EAAE,UAAU,WAAW,cAAc,OAAO,GAAG,4BAAc;AAAA,IACxE,qBAAC,SAAI,OAAO,EAAE,SAAS,QAAQ,KAAK,EAAE,GAMpC;AAAA;AAAA,QAAC;AAAA;AAAA,UACC,OAAO;AAAA,UACP,UAAU,CAAC,MAAM,QAAQ,EAAE,OAAO,KAAK;AAAA,UACvC,OAAO;AAAA,YACL,MAAM;AAAA,YACN,SAAS;AAAA,YACT,QAAQ;AAAA,YACR,cAAc;AAAA,UAChB;AAAA;AAAA,MACF;AAAA,MAEA;AAAA,QAAC;AAAA;AAAA,UACC,MAAK;AAAA,UACL,SAAS,YAAY;AAInB,kBAAM,IAAI,MAAM,QAAQ,EAAE,SAAS,EAAE,KAAK,GAAG,gBAAgB,CAAC,EAAE,CAAC;AACjE,sBAAU,GAAG,EAAE,OAAO,MAAM,EAAE,KAAK,GAAG;AAAA,UACxC;AAAA,UACA,OAAO;AAAA,YACL,SAAS;AAAA,YACT,QAAQ;AAAA,YACR,cAAc;AAAA,YACd,QAAQ;AAAA,UACV;AAAA,UACD;AAAA;AAAA,MAED;AAAA,OACF;AAAA,IACC,UACC,oBAAC,SAAI,OAAO,EAAE,WAAW,QAAQ,SAAS,UAAU,YAAY,UAAU,GAAI,kBAAO;AAAA,KAEzF;AAEJ;AAEA,IAAO,iBAAQ,mBAAmB;AAAA,EAChC,IAAI;AAAA,EACJ,OAAO;AAAA,IACL;AAAA,MACE,MAAM;AAAA,MACN,WAAW;AAAA,MACX,KAAK,EAAE,OAAO,UAAU;AAAA,IAC1B;AAAA,EACF;AACF,CAAC;","names":[]}
|
package/dist/server.d.ts
CHANGED
|
@@ -1,14 +1,18 @@
|
|
|
1
|
-
import { Context, Effect } from "@executor-js/sdk";
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
}>;
|
|
7
|
-
}
|
|
8
|
-
declare const ExampleExtensionService_base: Context.ServiceClass<ExampleExtensionService, "ExampleExtensionService", ExampleExtension>;
|
|
1
|
+
import { Context, Effect } from "@executor-js/sdk/core";
|
|
2
|
+
declare const ExampleExtensionService_base: Context.ServiceClass<ExampleExtensionService, "ExampleExtensionService", {
|
|
3
|
+
greet: (name: string) => Effect.Effect<{
|
|
4
|
+
message: string;
|
|
5
|
+
count: number;
|
|
6
|
+
}, never, never>;
|
|
7
|
+
}>;
|
|
9
8
|
export declare class ExampleExtensionService extends ExampleExtensionService_base {
|
|
10
9
|
}
|
|
11
|
-
export declare const examplePlugin: import("@executor-js/sdk").ConfiguredPlugin<"example",
|
|
10
|
+
export declare const examplePlugin: import("@executor-js/sdk/core").ConfiguredPlugin<"example", {
|
|
11
|
+
greet: (name: string) => Effect.Effect<{
|
|
12
|
+
message: string;
|
|
13
|
+
count: number;
|
|
14
|
+
}, never, never>;
|
|
15
|
+
}, {
|
|
12
16
|
count: number;
|
|
13
17
|
}, {}, undefined, typeof ExampleExtensionService, import("effect/Layer").Layer<import("effect/unstable/httpapi/HttpApiGroup").ApiGroup<"example", "example">, never, import("effect/unstable/http/HttpRouter").Request<"Requires", ExampleExtensionService>>, import("effect/unstable/httpapi/HttpApiGroup").HttpApiGroup<"example", import("effect/unstable/httpapi/HttpApiEndpoint").HttpApiEndpoint<"greet", "POST", "/greet", import("effect/unstable/httpapi/HttpApiEndpoint").StringTree<never>, import("effect/unstable/httpapi/HttpApiEndpoint").StringTree<never>, import("effect/unstable/httpapi/HttpApiEndpoint").Json<import("effect/Schema").Struct<{
|
|
14
18
|
readonly name: import("effect/Schema").String;
|
package/dist/server.js
CHANGED
|
@@ -1,16 +1,19 @@
|
|
|
1
1
|
import {
|
|
2
2
|
ExampleApi
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-M7BJ2IL4.js";
|
|
4
4
|
|
|
5
5
|
// src/server.ts
|
|
6
|
-
import {
|
|
7
|
-
Context,
|
|
8
|
-
definePlugin,
|
|
9
|
-
Effect,
|
|
10
|
-
HttpApi,
|
|
11
|
-
HttpApiBuilder
|
|
12
|
-
} from "@executor-js/sdk";
|
|
6
|
+
import { Context, definePlugin, Effect, HttpApi, HttpApiBuilder } from "@executor-js/sdk/core";
|
|
13
7
|
var ExampleApiBundle = HttpApi.make("example").add(ExampleApi);
|
|
8
|
+
var makeExampleExtension = (ctx) => ({
|
|
9
|
+
greet: (name) => Effect.sync(() => {
|
|
10
|
+
ctx.storage.count += 1;
|
|
11
|
+
return {
|
|
12
|
+
message: `hello ${name}`,
|
|
13
|
+
count: ctx.storage.count
|
|
14
|
+
};
|
|
15
|
+
})
|
|
16
|
+
});
|
|
14
17
|
var ExampleExtensionService = class extends Context.Service()("ExampleExtensionService") {
|
|
15
18
|
};
|
|
16
19
|
var ExampleHandlers = HttpApiBuilder.group(
|
|
@@ -32,15 +35,7 @@ var examplePlugin = definePlugin(() => ({
|
|
|
32
35
|
storage: () => ({ count: 0 }),
|
|
33
36
|
// Canonical implementation. CLI/tests/embedded callers and the HTTP
|
|
34
37
|
// handler all hit this same code path.
|
|
35
|
-
extension:
|
|
36
|
-
greet: (name) => Effect.sync(() => {
|
|
37
|
-
ctx.storage.count += 1;
|
|
38
|
-
return {
|
|
39
|
-
message: `hello ${name}`,
|
|
40
|
-
count: ctx.storage.count
|
|
41
|
-
};
|
|
42
|
-
})
|
|
43
|
-
}),
|
|
38
|
+
extension: makeExampleExtension,
|
|
44
39
|
routes: () => ExampleApi,
|
|
45
40
|
handlers: () => ExampleHandlers,
|
|
46
41
|
extensionService: ExampleExtensionService
|
package/dist/server.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/server.ts"],"sourcesContent":["// ---------------------------------------------------------------------------\n// @executor-js/plugin-example/server\n//\n// The server half of the example plugin. Demonstrates:\n// - extension methods that hold the canonical implementation\n// - an HttpApiGroup contributed via `routes`\n// - a late-binding `handlers` Layer that consumes the plugin's\n// extension via a Service tag (`ExampleExtensionService`); the host\n// binds the tag at boot for local or per request for cloud\n//\n// React and other browser-only deps live in `./client` — never here.\n// ---------------------------------------------------------------------------\n\nimport {
|
|
1
|
+
{"version":3,"sources":["../src/server.ts"],"sourcesContent":["// ---------------------------------------------------------------------------\n// @executor-js/plugin-example/server\n//\n// The server half of the example plugin. Demonstrates:\n// - extension methods that hold the canonical implementation\n// - an HttpApiGroup contributed via `routes`\n// - a late-binding `handlers` Layer that consumes the plugin's\n// extension via a Service tag (`ExampleExtensionService`); the host\n// binds the tag at boot for local or per request for cloud\n//\n// React and other browser-only deps live in `./client` — never here.\n// ---------------------------------------------------------------------------\n\nimport { Context, definePlugin, Effect, HttpApi, HttpApiBuilder } from \"@executor-js/sdk/core\";\n\nimport { ExampleApi } from \"./shared\";\n\n// Bundle the group into a single-group HttpApi for typing purposes only.\n// The runtime composition uses group identity to merge into the host's\n// FullApi, so this bundle never touches the host's wiring.\nconst ExampleApiBundle = HttpApi.make(\"example\").add(ExampleApi);\n\nconst makeExampleExtension = (ctx: { readonly storage: { count: number } }) => ({\n greet: (name: string) =>\n Effect.sync(() => {\n ctx.storage.count += 1;\n return {\n message: `hello ${name}`,\n count: ctx.storage.count,\n };\n }),\n});\n\ntype ExampleExtension = ReturnType<typeof makeExampleExtension>;\n\nexport class ExampleExtensionService extends Context.Service<\n ExampleExtensionService,\n ExampleExtension\n>()(\"ExampleExtensionService\") {}\n\nconst ExampleHandlers = HttpApiBuilder.group(ExampleApiBundle, \"example\", (h) =>\n h.handle(\"greet\", ({ payload }) =>\n Effect.gen(function* () {\n const ext = yield* ExampleExtensionService;\n return yield* ext.greet(payload.name);\n }),\n ),\n);\n\nexport const examplePlugin = definePlugin(() => ({\n id: \"example\" as const,\n packageName: \"@executor-js/plugin-example\",\n\n // No DB schema — the counter lives in plugin storage (in-memory) so\n // the example plugin doesn't pull in migration plumbing.\n storage: () => ({ count: 0 }),\n\n // Canonical implementation. CLI/tests/embedded callers and the HTTP\n // handler all hit this same code path.\n extension: makeExampleExtension,\n\n routes: () => ExampleApi,\n handlers: () => ExampleHandlers,\n extensionService: ExampleExtensionService,\n}));\n\nexport default examplePlugin;\n"],"mappings":";;;;;AAaA,SAAS,SAAS,cAAc,QAAQ,SAAS,sBAAsB;AAOvE,IAAM,mBAAmB,QAAQ,KAAK,SAAS,EAAE,IAAI,UAAU;AAE/D,IAAM,uBAAuB,CAAC,SAAkD;AAAA,EAC9E,OAAO,CAAC,SACN,OAAO,KAAK,MAAM;AAChB,QAAI,QAAQ,SAAS;AACrB,WAAO;AAAA,MACL,SAAS,SAAS,IAAI;AAAA,MACtB,OAAO,IAAI,QAAQ;AAAA,IACrB;AAAA,EACF,CAAC;AACL;AAIO,IAAM,0BAAN,cAAsC,QAAQ,QAGnD,EAAE,yBAAyB,EAAE;AAAC;AAEhC,IAAM,kBAAkB,eAAe;AAAA,EAAM;AAAA,EAAkB;AAAA,EAAW,CAAC,MACzE,EAAE;AAAA,IAAO;AAAA,IAAS,CAAC,EAAE,QAAQ,MAC3B,OAAO,IAAI,aAAa;AACtB,YAAM,MAAM,OAAO;AACnB,aAAO,OAAO,IAAI,MAAM,QAAQ,IAAI;AAAA,IACtC,CAAC;AAAA,EACH;AACF;AAEO,IAAM,gBAAgB,aAAa,OAAO;AAAA,EAC/C,IAAI;AAAA,EACJ,aAAa;AAAA;AAAA;AAAA,EAIb,SAAS,OAAO,EAAE,OAAO,EAAE;AAAA;AAAA;AAAA,EAI3B,WAAW;AAAA,EAEX,QAAQ,MAAM;AAAA,EACd,UAAU,MAAM;AAAA,EAChB,kBAAkB;AACpB,EAAE;AAEF,IAAO,iBAAQ;","names":[]}
|
package/dist/shared.d.ts
CHANGED
package/dist/shared.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@executor-js/plugin-example",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.1",
|
|
4
4
|
"homepage": "https://github.com/RhysSullivan/executor/tree/main/packages/plugins/example",
|
|
5
5
|
"bugs": {
|
|
6
6
|
"url": "https://github.com/RhysSullivan/executor/issues"
|
|
@@ -45,15 +45,7 @@
|
|
|
45
45
|
"typecheck:slow": "tsc --noEmit"
|
|
46
46
|
},
|
|
47
47
|
"dependencies": {
|
|
48
|
-
"@executor-js/sdk": "0.
|
|
49
|
-
},
|
|
50
|
-
"peerDependencies": {
|
|
51
|
-
"react": "^19.1.0"
|
|
52
|
-
},
|
|
53
|
-
"peerDependenciesMeta": {
|
|
54
|
-
"react": {
|
|
55
|
-
"optional": true
|
|
56
|
-
}
|
|
48
|
+
"@executor-js/sdk": "0.2.1"
|
|
57
49
|
},
|
|
58
50
|
"devDependencies": {
|
|
59
51
|
"@effect/vitest": "4.0.0-beta.59",
|
|
@@ -64,5 +56,13 @@
|
|
|
64
56
|
"tsup": "^8.5.0",
|
|
65
57
|
"typescript": "^5.9.3",
|
|
66
58
|
"vitest": "^4.1.5"
|
|
59
|
+
},
|
|
60
|
+
"peerDependencies": {
|
|
61
|
+
"react": "^19.1.0"
|
|
62
|
+
},
|
|
63
|
+
"peerDependenciesMeta": {
|
|
64
|
+
"react": {
|
|
65
|
+
"optional": true
|
|
66
|
+
}
|
|
67
67
|
}
|
|
68
68
|
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/shared.ts"],"sourcesContent":["// ---------------------------------------------------------------------------\n// @executor-js/plugin-example/shared\n//\n// Schemas and the HttpApiGroup definition shared between the server and\n// client halves. Both `./server` and `./client` import from here so the\n// frontend's typed reactive client and the backend's handlers see the\n// exact same payload/response/error contracts.\n//\n// No React or Node imports here — server and client both import this.\n// ---------------------------------------------------------------------------\n\nimport { HttpApiEndpoint, HttpApiGroup, Schema } from \"@executor-js/sdk\";\n\nexport const Greeting = Schema.Struct({\n message: Schema.String,\n count: Schema.Number,\n});\nexport type Greeting = typeof Greeting.Type;\n\nexport const ExampleApi = HttpApiGroup.make(\"example\").add(\n HttpApiEndpoint.post(\"greet\", \"/greet\", {\n payload: Schema.Struct({ name: Schema.String }),\n success: Greeting,\n }),\n);\n"],"mappings":";AAWA,SAAS,iBAAiB,cAAc,cAAc;AAE/C,IAAM,WAAW,OAAO,OAAO;AAAA,EACpC,SAAS,OAAO;AAAA,EAChB,OAAO,OAAO;AAChB,CAAC;AAGM,IAAM,aAAa,aAAa,KAAK,SAAS,EAAE;AAAA,EACrD,gBAAgB,KAAK,SAAS,UAAU;AAAA,IACtC,SAAS,OAAO,OAAO,EAAE,MAAM,OAAO,OAAO,CAAC;AAAA,IAC9C,SAAS;AAAA,EACX,CAAC;AACH;","names":[]}
|