-
-
Notifications
You must be signed in to change notification settings - Fork 2
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Durable Objects syntax idea #1
Comments
Current Interface: export const Counter = generateHonoObject("/counter", (app, state) => {
const { storage } = state;
app.post("/increment", async (c) => {
const newVal = 1 + ((await storage.get<number>("value")) || 0);
storage.put("value", newVal);
return c.text(newVal.toString());
});
app.post("/decrement", async (c) => {
const newVal = -1 + ((await storage.get<number>("value")) || 0);
storage.put("value", newVal);
return c.text(newVal.toString());
});
app.get("/", async (c) => {
const value = (await storage.get<number>("value")) || 0;
return c.text(value.toString());
});
}); |
Hono has an API called Variable in its context, and we are trying to map the contents of storage to this API to see if we can somehow achieve a clean interface. I tried to build a simpler vue-like interface by using Proxy to define getter and setter, but it seems to be unusable because Variable is Readonly. In the first place, get/set of storage itself is all Promise return value, so it seems impossible to make it Proxy. |
In #2, try to add React-like way to define the state! |
Personally I really like this: export const Counter = generateHonoObject("/counter", (app, state) => {
const { storage } = state;
app.post("/increment", async (c) => {
const newVal = 1 + ((await storage.get<number>("value")) || 0);
storage.put("value", newVal);
return c.text(newVal.toString());
});
app.post("/decrement", async (c) => {
const newVal = -1 + ((await storage.get<number>("value")) || 0);
storage.put("value", newVal);
return c.text(newVal.toString());
});
app.get("/", async (c) => {
const value = (await storage.get<number>("value")) || 0;
return c.text(value.toString());
});
}); My thought would be to make the That way you could do: export const Counter = generateHonoObject("/counter", async (app, state) => {
const { storage } = state;
const config = await storage.get('__CONFIG') ?? {}
app.post('/init', initValidator, async (c) => {
Object.assign(config, await c.req.json())
storage.put('__CONFIG', config)
})
app.use('/private/*',
basicAuth({
username: config.username,
password: config.password,
})
)
// ...
}) Does that make sense? |
Hi @geelen, I'm glad you like it. this is what you mean, right? export function generateHonoObject<
E extends Env = Env,
S extends Schema = Record<string, never>,
BasePath extends string = "/",
>(
basePath: string,
- cb: (app: Hono<E, S, BasePath>, state: DurableObjectState) => void,
+ cb: (app: Hono<E, S, BasePath>, state: DurableObjectState) => Promise<void>,
) {
const honoObject = function (
this: HonoObject<E, S, BasePath>,
state: DurableObjectState,
) {
const app = new Hono<E, S, BasePath>().basePath(basePath);
this.app = app;
- cb(app, state);
+ state.blockConcurrencyWhile(async () => {
+ await cb(app, state);
+ });
};
honoObject.prototype.fetch = function (
this: HonoObject<E, S, BasePath>,
request: Request,
) {
return this.app.fetch(request);
};
return honoObject;
} |
Hi, @geelen |
Durable Object is a very good representation in that it can store state and mutations as a single object.
However, if we could provide a third party, we would be able to ensure more flexibility and maintainability of notation.
ref: honojs/examples#86
For now, I implemented the simplest method I can think of at the moment to generate a HonoObject in
main
and a sample of it.As far as I know, Durable Object works by exporting the class itself, not the class instance.
Therefore, we tried to use the Constructor Function to generate dynamic classes while keeping the Hono interface easy to use.
If you have any ideas for a better interface, we'd love to hear your opinions and suggestions!
The text was updated successfully, but these errors were encountered: