import { Http } from "../decorators/httpserver.decorator.ts";
import { sleep } from "../utils/utils.ts";
@Http.ServerController({ schema: { fileName: "api.yaml" } })
class ExampleOpenAPI {}
const cryptoKey = await crypto.subtle.importKey(
"jwk",
JSON.parse(Deno.readTextFileSync("key.jwk")),
{ name: "HMAC", hash: "SHA-512" },
true,
[
"sign",
"verify",
],
);
@Http.ServerController()
class ExampleCustomAPI {
counter = 0;
@Http.Get("/api/:id")
get({ id, url }: { id: string; url: URL }) {
return {
body: `[GET /api/:id] 😎 (got id: "${id}", query: "${
decodeURIComponent(url.searchParams.toString())
}")`,
};
}
@Http.Post()
@Http.Auth({ cryptoKey })
async api(
{ url, request, auth }: {
url: URL;
request: Request;
auth: Record<string, unknown>;
},
) {
const data = await request.text();
return {
body: `[POST /api] 😎 (got data: "${data}", auth data: "${
JSON.stringify(auth)
}", query: "${
decodeURIComponent(url.searchParams.toString())
}", counter="${++this.counter}")`,
};
}
@Http.Get("/static/*")
static({ "*": path }: { "*": string }) {
return {
body: `[GET /static/*] 😎 (got path: "${path}")`,
};
}
}
@Http.ServerController()
class ExampleStream {
@Http.EventStream()
async *stream() {
yield ": Hello from stream\n\n";
while (true) {
await sleep(1000);
yield `event: tick\ndata: ${new Date().toISOString()}\n\n\n`;
}
}
}
@Http.ServerController()
class ExampleLimits {
@Http.Get()
@Http.RateLimit({ rps: 50 })
rpsTest() {}
}
console.log("Server started...");
Http.serve({
controllers: [ExampleOpenAPI, ExampleCustomAPI, ExampleStream, ExampleLimits],
});
import {
Actor,
Bindings,
Dapr,
PubSub,
Secrets,
Service,
State,
} from "../../decorators/dapr.decorator.ts";
const { TELEGRAM_CHATID, TELEGRAM_TOKEN } = await Secrets.getBulk({
store: "example-secrets-store",
});
const pubSubName = "pubsub";
@Dapr.AppController({ pubSubName })
class PubSubExample1 {
private s = "private1";
@PubSub.subscribeTo()
A({ data }: { data: unknown }) {
console.log("topicA =>", data, this);
}
@PubSub.subscribeTo()
B({ data }: { data: Record<string, unknown> }) {
console.log("topicB =>", data, this);
if (data.text && TELEGRAM_CHATID && TELEGRAM_TOKEN) {
const { text } = data;
const path =
`/bot${TELEGRAM_TOKEN}/sendMessage?chat_id=${TELEGRAM_CHATID}&text=${text}`;
Bindings.invoke({
bindingName: "telegram",
operation: "GET",
metadata: { path },
});
}
}
}
@Dapr.AppController({ pubSubName })
class PubSubExample2 {
private s = "private2";
@PubSub.subscribeTo({ metadata: { rawPayload: "true" } })
C(raw: Record<string, unknown>) {
console.log("topicC =>", raw, this);
}
}
@Dapr.AppController()
class PubSubExample3 {
private s = "private3";
@PubSub.subscribeTo({ pubSubName })
D({ data }: { data: unknown }) {
console.log("topicD =>", data, this);
console.log("publishing to topic A");
PubSub.publish({
pubSubName,
topicName: "A",
data,
});
}
}
@Dapr.AppController()
class ServiceExample1 {
private counter = 0;
@Service.expose()
async test({ request }: { request: Request }) {
console.log(`test service called, counter: <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mrow><mo>+</mo><mo>+</mo><mi>t</mi><mi>h</mi><mi>i</mi><mi>s</mi><mi mathvariant="normal">.</mi><mi>c</mi><mi>o</mi><mi>u</mi><mi>n</mi><mi>t</mi><mi>e</mi><mi>r</mi></mrow><mo separator="true">,</mo><mi>d</mi><mi>a</mi><mi>t</mi><mi>a</mi><mo>=</mo><mi mathvariant="normal">"</mi></mrow><annotation encoding="application/x-tex">{++this.counter}, data = "</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8889em;vertical-align:-0.1944em;"></span><span class="mord"><span class="mord">+</span><span class="mspace" style="margin-right:0.2222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222em;"></span><span class="mord mathnormal">t</span><span class="mord mathnormal">hi</span><span class="mord mathnormal">s</span><span class="mord">.</span><span class="mord mathnormal">co</span><span class="mord mathnormal">u</span><span class="mord mathnormal">n</span><span class="mord mathnormal">t</span><span class="mord mathnormal" style="margin-right:0.02778em;">er</span></span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.1667em;"></span><span class="mord mathnormal">d</span><span class="mord mathnormal">a</span><span class="mord mathnormal">t</span><span class="mord mathnormal">a</span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="base"><span class="strut" style="height:0.6944em;"></span><span class="mord">"</span></span></span></span>{await request.text()}"`);
return {
body: `test reply, counter: ${this.counter}`,
};
}
@Bindings.listenTo()
tweets({ text }: { text: Record<string, unknown> }) {
console.log(`🐦 => "${text}"`);
}
}
@Dapr.AppController()
class TestActor1 {
private counter = 0;
@Actor.event()
activate({ actorType, actorId }: { actorType: string; actorId: string }) {
console.log("TestActor1 activated", this);
this.counter = 0;
Actor.setReminder({
actorType,
actorId,
reminderName: "reminder",
period: "5s",
});
}
@Actor.event()
async deactivate({ actorType, actorId }: { actorType: string; actorId: string }) {
console.log("TestActor1 deactivation", this);
const reminder = await Actor.getReminder({actorType, actorId, reminderName: "reminder"});
console.log("reminder =>", reminder);
await Actor.deleteReminder({ actorType, actorId, reminderName: "reminder" });
}
@Actor.event()
reminder() {
console.log("TestActor1 reminder called");
}
@Actor.method()
async testMethod1({ request }: { request: Request }) {
const data = await request.text();
console.log(
"TestActor1/testMethod1() called, data =",
data,
", counter =",
++this.counter,
);
}
}
@Dapr.AppController()
class TestActor2 {
private readonly tag = "TestActor2";
@Actor.method()
testMethod1({ actorType, actorId }: { actorType: string; actorId: string }) {
console.log("TestActor2/testMethod1() called,", this);
Actor.setTimer({ actorType, actorId, timerName: "timer", dueTime: "10s" });
}
@Actor.event()
timer() {
console.log("TestActor2/timer fired");
}
}
await State.set({
storename: "example-state-store",
data: [{ key: "key1", value: "value1" }, { key: "key3", value: "value3" }],
});
console.log("key1=", await State.get({ storename: "example-state-store", key: "key1" }));
console.log("missing=", await State.get({storename: "example-state-store", key: "missing" }));
console.log("bulk=", await State.getBulk({storename: "example-state-store", data: { keys: ["key1", "missing", "key3"] }}));
console.log("Dapr app started...");
Dapr.start({
appPort: 3000,
actorIdleTimeout: "5s",
controllers: [
PubSubExample1,
PubSubExample2,
PubSubExample3,
ServiceExample1,
TestActor1,
TestActor2,
],
});