import {
Actor,
ActorEvent,
Bindings,
Dapr,
PubSub,
Secrets,
Service,
State,
} from "../../decorators/dapr.decorator.ts";
import { sleep } from "../../utils/utils.ts";
const { TELEGRAM_CHATID, TELEGRAM_TOKEN } = await Secrets.getBulk({
store: "example-secrets-store",
});
const PUBSUBNAME = "pubsub";
@Dapr.App()
class ExampleApp {
@PubSub.subscribe({ pubSubName: PUBSUBNAME, topic: "A" })
topicA({ data }: { data: unknown }) {
console.log("topicA =>", data);
}
@PubSub.subscribe({ pubSubName: PUBSUBNAME, topic: "B" })
topicB({ data }: { data: Record<string, unknown> }) {
console.log("topicB =>", data);
if (data.text && TELEGRAM_CHATID && TELEGRAM_TOKEN) {
const { text } = data;
const path =
`/bot${TELEGRAM_TOKEN}/sendMessage?chat_id=${TELEGRAM_CHATID}&text=${text}`;
Bindings.invoke({
name: "telegram",
operation: "get",
metadata: { path },
});
}
}
@PubSub.subscribe({
pubSubName: PUBSUBNAME,
topic: "C",
metadata: { rawPayload: "true" },
})
topicC(raw: Record<string, unknown>) {
console.log("topicC =>", raw);
}
@Bindings.listenTo({ name: "tweets" })
tweets({ text }: { text: Record<string, unknown> }) {
PubSub.publish({
data: { text },
pubSubName: PUBSUBNAME,
topic: "A",
});
}
private counter = 0;
@Service.expose({ name: "test", verb: "GET" })
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()}"`,
);
await sleep(4000);
return {
body: `test reply, counter: ${this.counter}`,
};
}
}
@Dapr.App()
class ExampleActor {
counter = 0;
@Actor.registerEventHandler({
actorType: "testActor",
event: ActorEvent.Activate,
})
async activate(
{ actorType, actorId }: { actorType: string; actorId: string },
) {
this.counter = 0;
console.log(
`testActor with actorId="${actorId}" activated, counter reset\nCreating reminder and timer...`,
);
await Actor.createReminder({
actorType,
actorId,
reminderName: "testReminder",
dueTime: "20s",
period: "0",
});
await Actor.createTimer({
actorType,
actorId,
timerName: "testTimer",
dueTime: "5s",
period: "0s",
});
}
@Actor.registerEventHandler({
actorType: "testActor",
event: ActorEvent.Deactivate,
})
deactivate({ actorId }: { actorId: string }) {
console.log(`testActor with actorId="${actorId}" deactivated`);
}
@Actor.registerMethod({
actorType: "testActor",
methodName: "testReminder",
})
testReminder(
{ actorType, actorId, methodName }: {
actorType: string;
actorId: string;
methodName: string;
},
) {
console.log(
`⏱ Actor reminder invoked, actorType="${actorType}", actorId="${actorId}", reminder="${methodName}"`,
);
}
@Actor.registerMethod({
actorType: "testActor",
methodName: "testTimer",
})
testTimer(
{ actorType, actorId, methodName }: {
actorType: string;
actorId: string;
methodName: string;
},
) {
console.log(
`⏰ Actor timer invoked, actorType="${actorType}", actorId="${actorId}", reminder="${methodName}"`,
);
}
@Actor.registerMethod({
actorType: "testActor",
methodName: "testMethod1",
})
async testMethod1(
{ actorId, request }: { actorId: string; request: Request },
) {
const data = await request.text();
console.log(
`actor invoked with data="${data}", actorType="testActor", actorId="${actorId}", method="testMethod"`,
);
return `counter: ${++this.counter}`;
}
@Actor.registerMethod({
actorType: "testActor",
methodName: "testMethod2",
})
async testMethod2(
{ actorType, actorId, methodName, request }: {
actorType: string;
actorId: string;
methodName: string;
request: Request;
},
) {
const data = await request.text();
console.log(
`actor invoked with data="${data}", actorType="${actorType}", actorId="${actorId}", method="${methodName}"`,
);
if (this.counter < 10) {
Actor.invoke({
actorType,
actorId,
methodName,
data: `test data from myself, counter=${this.counter}`,
});
}
return `counter: ${++this.counter}`;
}
}
await State.set({
storename: "example-state-store",
data: [{ key: "key1", value: "value1" }, { key: "key3", value: "value3" }],
});
console.log(
`key1=${
JSON.stringify(
await (await State.get({ storename: "example-state-store", key: "key1" }))
.text(),
)
}`,
);
console.log(
`missing=${
JSON.stringify(
await (await State.get({
storename: "example-state-store",
key: "missing",
})).text(),
)
}`,
);
console.log(
`bulk=${
JSON.stringify(
await (await State.getBulk({
storename: "example-state-store",
data: { keys: ["key1", "missing", "key3"] },
})).text(),
)
}`,
);
console.log("Dapr app started...");
Dapr.start({ appPort: 3000, actorIdleTimeout: "5s" });