@krak-stack/registry 0.1.0

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.
Files changed (84) hide show
  1. package/README.md +29 -0
  2. package/dist/components/ui/alert-dialog.d.ts +18 -0
  3. package/dist/components/ui/app-brand.d.ts +26 -0
  4. package/dist/components/ui/app-brand.js +78 -0
  5. package/dist/components/ui/attachment.d.ts +23 -0
  6. package/dist/components/ui/badge.d.ts +7 -0
  7. package/dist/components/ui/button.d.ts +8 -0
  8. package/dist/components/ui/card.d.ts +11 -0
  9. package/dist/components/ui/checkbox.d.ts +3 -0
  10. package/dist/components/ui/code-block.d.ts +14 -0
  11. package/dist/components/ui/code-block.js +224 -0
  12. package/dist/components/ui/command.d.ts +18 -0
  13. package/dist/components/ui/copy-button.d.ts +18 -0
  14. package/dist/components/ui/copy-button.js +133 -0
  15. package/dist/components/ui/data-table.d.ts +264 -0
  16. package/dist/components/ui/data-table.js +3594 -0
  17. package/dist/components/ui/dialog.d.ts +13 -0
  18. package/dist/components/ui/dropdown-menu.d.ts +29 -0
  19. package/dist/components/ui/editing-locale-switcher.d.ts +7 -0
  20. package/dist/components/ui/editing-locale-switcher.js +626 -0
  21. package/dist/components/ui/effect-form.d.ts +137 -0
  22. package/dist/components/ui/effect-form.js +2330 -0
  23. package/dist/components/ui/field.d.ts +24 -0
  24. package/dist/components/ui/file-picker.d.ts +30 -0
  25. package/dist/components/ui/file-picker.js +811 -0
  26. package/dist/components/ui/form.d.ts +402 -0
  27. package/dist/components/ui/form.js +2245 -0
  28. package/dist/components/ui/google-map.d.ts +103 -0
  29. package/dist/components/ui/google-map.js +754 -0
  30. package/dist/components/ui/icon-input.d.ts +9 -0
  31. package/dist/components/ui/icon-input.js +971 -0
  32. package/dist/components/ui/input-group.d.ts +17 -0
  33. package/dist/components/ui/input.d.ts +3 -0
  34. package/dist/components/ui/label.d.ts +3 -0
  35. package/dist/components/ui/loading.d.ts +7 -0
  36. package/dist/components/ui/loading.js +467 -0
  37. package/dist/components/ui/locale-switcher.d.ts +7 -0
  38. package/dist/components/ui/locale-switcher.js +632 -0
  39. package/dist/components/ui/pagination.d.ts +43 -0
  40. package/dist/components/ui/pagination.js +787 -0
  41. package/dist/components/ui/popover.d.ts +9 -0
  42. package/dist/components/ui/scroll-area.d.ts +4 -0
  43. package/dist/components/ui/search-menu.d.ts +34 -0
  44. package/dist/components/ui/search-menu.js +839 -0
  45. package/dist/components/ui/select.d.ts +15 -0
  46. package/dist/components/ui/separator.d.ts +3 -0
  47. package/dist/components/ui/sheet.d.ts +14 -0
  48. package/dist/components/ui/sidebar-layout.d.ts +29 -0
  49. package/dist/components/ui/sidebar-layout.js +755 -0
  50. package/dist/components/ui/sidebar.d.ts +63 -0
  51. package/dist/components/ui/skeleton.d.ts +2 -0
  52. package/dist/components/ui/stats-card.d.ts +12 -0
  53. package/dist/components/ui/stats-card.js +125 -0
  54. package/dist/components/ui/table.d.ts +10 -0
  55. package/dist/components/ui/textarea.d.ts +3 -0
  56. package/dist/components/ui/theme-switcher.d.ts +29 -0
  57. package/dist/components/ui/theme-switcher.js +775 -0
  58. package/dist/components/ui/tooltip.d.ts +6 -0
  59. package/dist/components/ui/virtualized-combobox.d.ts +54 -0
  60. package/dist/components/ui/virtualized-combobox.js +821 -0
  61. package/dist/hooks/use-mobile.d.ts +1 -0
  62. package/dist/lib/query.d.ts +49 -0
  63. package/dist/lib/utils.d.ts +2 -0
  64. package/dist/paraglide/runtime.d.ts +978 -0
  65. package/dist/services/embedding.d.ts +2 -0
  66. package/dist/services/embedding.js +23 -0
  67. package/dist/services/notification/channels/index.d.ts +22 -0
  68. package/dist/services/notification/channels/index.js +11 -0
  69. package/dist/services/notification/channels/ses/index.d.ts +51 -0
  70. package/dist/services/notification/channels/ses/index.js +145 -0
  71. package/dist/services/notification/channels/ses/schema.d.ts +13 -0
  72. package/dist/services/notification/channels/ses/schema.js +35 -0
  73. package/dist/services/notification/index.d.ts +15 -0
  74. package/dist/services/notification/index.js +67 -0
  75. package/dist/services/notification/schema.d.ts +10 -0
  76. package/dist/services/notification/schema.js +30 -0
  77. package/dist/services/opentelemetry.d.ts +8 -0
  78. package/dist/services/opentelemetry.js +23 -0
  79. package/dist/services/s3/index.d.ts +62 -0
  80. package/dist/services/s3/index.js +208 -0
  81. package/dist/services/s3/schema.d.ts +18 -0
  82. package/dist/services/s3/schema.js +37 -0
  83. package/package.json +218 -0
  84. package/tailwind.css +1 -0
@@ -0,0 +1,2 @@
1
+ import { Config, Layer } from "effect";
2
+ export declare const EmbeddingLayer: Layer.Layer<import("effect/unstable/ai/EmbeddingModel").EmbeddingModel, Config.ConfigError, never>;
@@ -0,0 +1,23 @@
1
+ // ../../src/services/embedding.ts
2
+ import { OpenAiClient, OpenAiEmbeddingModel } from "@effect/ai-openai-compat";
3
+ import { Config, Effect, Layer, Redacted } from "effect";
4
+ import { FetchHttpClient } from "effect/unstable/http";
5
+ var EmbeddingLayer = Layer.unwrap(Effect.gen(function* () {
6
+ const apiUrl = yield* Config.string("EMBEDDINGS_URL");
7
+ const embeddingModel = yield* Config.string("EMBEDDINGS_MODEL");
8
+ const embeddingDimensions = yield* Config.number("EMBEDDINGS_DIMENSIONS");
9
+ const embeddingClientLayer = OpenAiClient.layer({
10
+ apiKey: Redacted.make("embedding"),
11
+ apiUrl
12
+ });
13
+ return OpenAiEmbeddingModel.layer({
14
+ model: embeddingModel,
15
+ config: {
16
+ dimensions: embeddingDimensions,
17
+ encoding_format: "float"
18
+ }
19
+ }).pipe(Layer.provide(embeddingClientLayer), Layer.provide(FetchHttpClient.layer));
20
+ }));
21
+ export {
22
+ EmbeddingLayer
23
+ };
@@ -0,0 +1,22 @@
1
+ import { Context, Effect, Layer } from "effect";
2
+ import { NotificationSendError } from "../schema.js";
3
+ export interface NotificationChannels {
4
+ }
5
+ export type NotificationMessage = keyof NotificationChannels extends never ? Record<string, unknown> : Partial<{
6
+ readonly [Key in keyof NotificationChannels]: NotificationChannels[Key];
7
+ }>;
8
+ export interface NotificationChannelShape<Key extends string = string, Payload = unknown> {
9
+ readonly key: Key;
10
+ readonly send: (payload: unknown, message: NotificationMessage) => Effect.Effect<void, NotificationSendError>;
11
+ readonly payload?: Payload;
12
+ }
13
+ export interface NotificationChannelRegistryShape {
14
+ readonly channels: ReadonlyArray<NotificationChannelShape>;
15
+ }
16
+ declare const NotificationChannelRegistry_base: Context.ServiceClass<NotificationChannelRegistry, "NotificationChannelRegistry", NotificationChannelRegistryShape>;
17
+ export declare class NotificationChannelRegistry extends NotificationChannelRegistry_base {
18
+ static readonly make: (...channels: ReadonlyArray<NotificationChannelShape>) => NotificationChannelRegistryShape;
19
+ static readonly layer: (channels: ReadonlyArray<NotificationChannelShape>) => Layer.Layer<NotificationChannelRegistry, never, never>;
20
+ static readonly emptyLayer: Layer.Layer<NotificationChannelRegistry, never, never>;
21
+ }
22
+ export {};
@@ -0,0 +1,11 @@
1
+ // ../../src/services/notification/channels/index.ts
2
+ import { Context, Layer } from "effect";
3
+
4
+ class NotificationChannelRegistry extends Context.Service()("NotificationChannelRegistry") {
5
+ static make = (...channels) => ({ channels });
6
+ static layer = (channels) => Layer.succeed(this, this.make(...channels));
7
+ static emptyLayer = Layer.succeed(this, this.make());
8
+ }
9
+ export {
10
+ NotificationChannelRegistry
11
+ };
@@ -0,0 +1,51 @@
1
+ import { Config, Context, Effect, Layer, Redacted } from "effect";
2
+ import { type NotificationChannelShape } from "..";
3
+ import { SesEmailNotification } from "./schema.js";
4
+ declare module ".." {
5
+ interface NotificationChannels {
6
+ readonly email: SesEmailNotification;
7
+ }
8
+ }
9
+ interface SesAccessKey {
10
+ readonly id: Redacted.Redacted<string>;
11
+ readonly secret: Redacted.Redacted<string>;
12
+ }
13
+ interface SesIdentity {
14
+ readonly region: string;
15
+ readonly from: string | undefined;
16
+ }
17
+ interface SesNotificationConfigShape {
18
+ readonly identity: SesIdentity;
19
+ readonly accessKey: SesAccessKey;
20
+ }
21
+ declare const SesNotificationConfig_base: Context.ServiceClass<SesNotificationConfig, "SesNotificationConfig", SesNotificationConfigShape> & {
22
+ readonly make: Effect.Effect<SesNotificationConfigShape, Config.ConfigError, never>;
23
+ };
24
+ export declare class SesNotificationConfig extends SesNotificationConfig_base {
25
+ static readonly layer: Layer.Layer<SesNotificationConfig, Config.ConfigError, never>;
26
+ }
27
+ declare const SesNotificationChannel_base: Context.ServiceClass<SesNotificationChannel, "SesNotificationChannel", NotificationChannelShape<"email", {
28
+ readonly from?: string | undefined;
29
+ readonly to: string | readonly [string, ...string[]];
30
+ readonly cc?: readonly string[] | undefined;
31
+ readonly bcc?: readonly string[] | undefined;
32
+ readonly replyTo?: readonly string[] | undefined;
33
+ readonly subject: string;
34
+ readonly text?: string | undefined;
35
+ readonly html?: string | undefined;
36
+ }>> & {
37
+ readonly make: Effect.Effect<NotificationChannelShape<"email", {
38
+ readonly from?: string | undefined;
39
+ readonly to: string | readonly [string, ...string[]];
40
+ readonly cc?: readonly string[] | undefined;
41
+ readonly bcc?: readonly string[] | undefined;
42
+ readonly replyTo?: readonly string[] | undefined;
43
+ readonly subject: string;
44
+ readonly text?: string | undefined;
45
+ readonly html?: string | undefined;
46
+ }>, never, SesNotificationConfig>;
47
+ };
48
+ export declare class SesNotificationChannel extends SesNotificationChannel_base {
49
+ static readonly layer: Layer.Layer<SesNotificationChannel, Config.ConfigError, never>;
50
+ }
51
+ export {};
@@ -0,0 +1,145 @@
1
+ // ../../src/services/notification/channels/ses/index.ts
2
+ import {
3
+ SESv2Client,
4
+ SendEmailCommand
5
+ } from "@aws-sdk/client-sesv2";
6
+ import { Config, Context, Effect, Layer, Redacted, Schema as Schema3 } from "effect";
7
+
8
+ // ../../src/services/notification/schema.ts
9
+ import { Schema } from "effect";
10
+ var NotificationMessageSchema = Schema.Record(Schema.String, Schema.Unknown).annotate({
11
+ identifier: "NotificationMessage",
12
+ title: "Notification message",
13
+ description: "A dynamic notification envelope keyed by channel capability. Installed channels send the payload matching their key.",
14
+ examples: [
15
+ {
16
+ email: {
17
+ to: "user@example.com",
18
+ subject: "Welcome",
19
+ text: "Thanks for signing up."
20
+ },
21
+ discord: {
22
+ content: "A user signed up."
23
+ }
24
+ }
25
+ ]
26
+ });
27
+
28
+ class NotificationSendError extends Schema.TaggedErrorClass()("NotificationSendError", {
29
+ message: Schema.String,
30
+ channel: Schema.optional(Schema.String),
31
+ error: Schema.optional(Schema.Defect())
32
+ }) {
33
+ }
34
+
35
+ // ../../src/services/notification/channels/ses/schema.ts
36
+ import { Schema as Schema2 } from "effect";
37
+ var SesEmailAddress = Schema2.NonEmptyString.annotate({
38
+ identifier: "SesEmailAddress",
39
+ title: "SES email address",
40
+ description: "An email address used by the SES notification channel.",
41
+ examples: ["user@example.com"]
42
+ });
43
+ var SesEmailNotification = Schema2.Struct({
44
+ from: Schema2.optional(SesEmailAddress),
45
+ to: Schema2.Union([SesEmailAddress, Schema2.NonEmptyArray(SesEmailAddress)]),
46
+ cc: Schema2.optional(Schema2.Array(SesEmailAddress)),
47
+ bcc: Schema2.optional(Schema2.Array(SesEmailAddress)),
48
+ replyTo: Schema2.optional(Schema2.Array(SesEmailAddress)),
49
+ subject: Schema2.NonEmptyString,
50
+ text: Schema2.optional(Schema2.NonEmptyString),
51
+ html: Schema2.optional(Schema2.NonEmptyString)
52
+ }).annotate({
53
+ identifier: "SesEmailNotification",
54
+ title: "SES email notification",
55
+ description: "Email notification payload handled by the SES notification channel. At least one of text or html must be provided when sending.",
56
+ examples: [
57
+ {
58
+ from: "KrakStack <no-reply@example.com>",
59
+ to: "user@example.com",
60
+ subject: "Welcome",
61
+ text: "Thanks for signing up.",
62
+ html: "<p>Thanks for signing up.</p>"
63
+ }
64
+ ]
65
+ });
66
+
67
+ // ../../src/services/notification/channels/ses/index.ts
68
+ class SesNotificationConfig extends Context.Service()("SesNotificationConfig", {
69
+ make: Effect.gen(function* () {
70
+ const region = yield* Config.string("SES_REGION");
71
+ const id = yield* Config.redacted("SES_ACCESS_KEY_ID");
72
+ const secret = yield* Config.redacted("SES_SECRET_ACCESS_KEY");
73
+ const from = yield* Config.string("NOTIFICATION_EMAIL_FROM").pipe(Config.orElse(() => Config.succeed("")));
74
+ return {
75
+ identity: { region, from: from || undefined },
76
+ accessKey: { id, secret }
77
+ };
78
+ })
79
+ }) {
80
+ static layer = Layer.effect(this, this.make);
81
+ }
82
+
83
+ class SesNotificationChannel extends Context.Service()("SesNotificationChannel", {
84
+ make: Effect.gen(function* () {
85
+ const { accessKey, identity } = yield* SesNotificationConfig;
86
+ const client = new SESv2Client({
87
+ region: identity.region,
88
+ credentials: {
89
+ accessKeyId: Redacted.value(accessKey.id),
90
+ secretAccessKey: Redacted.value(accessKey.secret)
91
+ }
92
+ });
93
+ const send = Effect.fn("SesNotificationChannel.send")(function* (payload, _message) {
94
+ const email = yield* decodeEmail(payload);
95
+ const from = email.from ?? identity.from;
96
+ if (!from) {
97
+ return yield* notificationSendError("SES email notification requires from or NOTIFICATION_EMAIL_FROM");
98
+ }
99
+ const body = yield* requireBody(email);
100
+ const emailMessage = {
101
+ Subject: { Data: email.subject, Charset: "UTF-8" },
102
+ Body: body
103
+ };
104
+ yield* Effect.tryPromise({
105
+ try: () => client.send(new SendEmailCommand({
106
+ FromEmailAddress: from,
107
+ Destination: buildDestination(email),
108
+ Content: { Simple: emailMessage },
109
+ ...email.replyTo?.length ? { ReplyToAddresses: Array.from(email.replyTo) } : {}
110
+ })),
111
+ catch: (error) => notificationSendError("Failed to send SES email", error)
112
+ });
113
+ });
114
+ return { key: "email", send };
115
+ })
116
+ }) {
117
+ static layer = Layer.effect(this, this.make).pipe(Layer.provide(SesNotificationConfig.layer));
118
+ }
119
+ var notificationSendError = (message, error) => new NotificationSendError({
120
+ channel: "email",
121
+ message,
122
+ ...error === undefined ? {} : { error }
123
+ });
124
+ var decodeEmail = (payload) => Schema3.decodeUnknownEffect(SesEmailNotification)(payload).pipe(Effect.mapError((error) => notificationSendError("Invalid SES email notification payload", error)));
125
+ var requireBody = (email) => {
126
+ const { html, text } = email;
127
+ if (!html && !text) {
128
+ return Effect.fail(notificationSendError("SES email notification requires text or html"));
129
+ }
130
+ const body = {
131
+ ...text ? { Text: { Data: text, Charset: "UTF-8" } } : {},
132
+ ...html ? { Html: { Data: html, Charset: "UTF-8" } } : {}
133
+ };
134
+ return Effect.succeed(body);
135
+ };
136
+ var recipients = (to) => Array.isArray(to) ? Array.from(to) : [to];
137
+ var buildDestination = (email) => ({
138
+ ToAddresses: recipients(email.to),
139
+ ...email.cc?.length ? { CcAddresses: Array.from(email.cc) } : {},
140
+ ...email.bcc?.length ? { BccAddresses: Array.from(email.bcc) } : {}
141
+ });
142
+ export {
143
+ SesNotificationConfig,
144
+ SesNotificationChannel
145
+ };
@@ -0,0 +1,13 @@
1
+ import { Schema } from "effect";
2
+ export declare const SesEmailAddress: Schema.NonEmptyString;
3
+ export declare const SesEmailNotification: Schema.Struct<{
4
+ readonly from: Schema.optional<Schema.NonEmptyString>;
5
+ readonly to: Schema.Union<readonly [Schema.NonEmptyString, Schema.NonEmptyArray<Schema.NonEmptyString>]>;
6
+ readonly cc: Schema.optional<Schema.$Array<Schema.NonEmptyString>>;
7
+ readonly bcc: Schema.optional<Schema.$Array<Schema.NonEmptyString>>;
8
+ readonly replyTo: Schema.optional<Schema.$Array<Schema.NonEmptyString>>;
9
+ readonly subject: Schema.NonEmptyString;
10
+ readonly text: Schema.optional<Schema.NonEmptyString>;
11
+ readonly html: Schema.optional<Schema.NonEmptyString>;
12
+ }>;
13
+ export type SesEmailNotification = typeof SesEmailNotification.Type;
@@ -0,0 +1,35 @@
1
+ // ../../src/services/notification/channels/ses/schema.ts
2
+ import { Schema } from "effect";
3
+ var SesEmailAddress = Schema.NonEmptyString.annotate({
4
+ identifier: "SesEmailAddress",
5
+ title: "SES email address",
6
+ description: "An email address used by the SES notification channel.",
7
+ examples: ["user@example.com"]
8
+ });
9
+ var SesEmailNotification = Schema.Struct({
10
+ from: Schema.optional(SesEmailAddress),
11
+ to: Schema.Union([SesEmailAddress, Schema.NonEmptyArray(SesEmailAddress)]),
12
+ cc: Schema.optional(Schema.Array(SesEmailAddress)),
13
+ bcc: Schema.optional(Schema.Array(SesEmailAddress)),
14
+ replyTo: Schema.optional(Schema.Array(SesEmailAddress)),
15
+ subject: Schema.NonEmptyString,
16
+ text: Schema.optional(Schema.NonEmptyString),
17
+ html: Schema.optional(Schema.NonEmptyString)
18
+ }).annotate({
19
+ identifier: "SesEmailNotification",
20
+ title: "SES email notification",
21
+ description: "Email notification payload handled by the SES notification channel. At least one of text or html must be provided when sending.",
22
+ examples: [
23
+ {
24
+ from: "KrakStack <no-reply@example.com>",
25
+ to: "user@example.com",
26
+ subject: "Welcome",
27
+ text: "Thanks for signing up.",
28
+ html: "<p>Thanks for signing up.</p>"
29
+ }
30
+ ]
31
+ });
32
+ export {
33
+ SesEmailNotification,
34
+ SesEmailAddress
35
+ };
@@ -0,0 +1,15 @@
1
+ import { Context, Effect, Layer } from "effect";
2
+ import { NotificationChannelRegistry, type NotificationMessage, type NotificationChannelShape } from "./channels/index.js";
3
+ import { NotificationSendError } from "./schema.js";
4
+ export interface NotificationServiceShape {
5
+ readonly send: (message: NotificationMessage) => Effect.Effect<void, NotificationSendError>;
6
+ }
7
+ declare const NotificationService_base: Context.ServiceClass<NotificationService, "NotificationService", NotificationServiceShape> & {
8
+ readonly make: Effect.Effect<NotificationServiceShape, never, NotificationChannelRegistry>;
9
+ };
10
+ export declare class NotificationService extends NotificationService_base {
11
+ static readonly layer: Layer.Layer<NotificationService, never, NotificationChannelRegistry>;
12
+ static readonly makeLayer: (channels: ReadonlyArray<NotificationChannelShape>) => Layer.Layer<NotificationService, never, never>;
13
+ static readonly noopLayer: Layer.Layer<NotificationService, never, never>;
14
+ }
15
+ export {};
@@ -0,0 +1,67 @@
1
+ // ../../src/services/notification/index.ts
2
+ import { Context as Context2, Effect as Effect2, Layer as Layer2 } from "effect";
3
+
4
+ // ../../src/services/notification/channels/index.ts
5
+ import { Context, Layer } from "effect";
6
+
7
+ class NotificationChannelRegistry extends Context.Service()("NotificationChannelRegistry") {
8
+ static make = (...channels) => ({ channels });
9
+ static layer = (channels) => Layer.succeed(this, this.make(...channels));
10
+ static emptyLayer = Layer.succeed(this, this.make());
11
+ }
12
+
13
+ // ../../src/services/notification/schema.ts
14
+ import { Schema } from "effect";
15
+ var NotificationMessageSchema = Schema.Record(Schema.String, Schema.Unknown).annotate({
16
+ identifier: "NotificationMessage",
17
+ title: "Notification message",
18
+ description: "A dynamic notification envelope keyed by channel capability. Installed channels send the payload matching their key.",
19
+ examples: [
20
+ {
21
+ email: {
22
+ to: "user@example.com",
23
+ subject: "Welcome",
24
+ text: "Thanks for signing up."
25
+ },
26
+ discord: {
27
+ content: "A user signed up."
28
+ }
29
+ }
30
+ ]
31
+ });
32
+
33
+ class NotificationSendError extends Schema.TaggedErrorClass()("NotificationSendError", {
34
+ message: Schema.String,
35
+ channel: Schema.optional(Schema.String),
36
+ error: Schema.optional(Schema.Defect())
37
+ }) {
38
+ }
39
+
40
+ // ../../src/services/notification/index.ts
41
+ class NotificationService extends Context2.Service()("NotificationService", {
42
+ make: Effect2.gen(function* () {
43
+ const registry = yield* NotificationChannelRegistry;
44
+ const send = Effect2.fn("NotificationService.send")((message) => Effect2.gen(function* () {
45
+ for (const [key, payload] of Object.entries(message)) {
46
+ const channels = registry.channels.filter((item) => item.key === key);
47
+ if (channels.length === 0) {
48
+ return yield* new NotificationSendError({
49
+ channel: key,
50
+ message: `No notification channel installed for ${key}`
51
+ });
52
+ }
53
+ yield* Effect2.forEach(channels, (channel) => channel.send(payload, message));
54
+ }
55
+ }));
56
+ return { send };
57
+ })
58
+ }) {
59
+ static layer = Layer2.effect(this, this.make);
60
+ static makeLayer = (channels) => this.layer.pipe(Layer2.provide(NotificationChannelRegistry.layer(channels)));
61
+ static noopLayer = Layer2.succeed(this, {
62
+ send: () => Effect2.void
63
+ });
64
+ }
65
+ export {
66
+ NotificationService
67
+ };
@@ -0,0 +1,10 @@
1
+ import { Schema } from "effect";
2
+ export declare const NotificationMessageSchema: Schema.$Record<Schema.String, Schema.Unknown>;
3
+ declare const NotificationSendError_base: Schema.Class<NotificationSendError, Schema.TaggedStruct<"NotificationSendError", {
4
+ readonly message: Schema.String;
5
+ readonly channel: Schema.optional<Schema.String>;
6
+ readonly error: Schema.optional<Schema.Defect>;
7
+ }>, import("effect/Cause").YieldableError>;
8
+ export declare class NotificationSendError extends NotificationSendError_base {
9
+ }
10
+ export type { NotificationMessage } from "./channels/index.js";
@@ -0,0 +1,30 @@
1
+ // ../../src/services/notification/schema.ts
2
+ import { Schema } from "effect";
3
+ var NotificationMessageSchema = Schema.Record(Schema.String, Schema.Unknown).annotate({
4
+ identifier: "NotificationMessage",
5
+ title: "Notification message",
6
+ description: "A dynamic notification envelope keyed by channel capability. Installed channels send the payload matching their key.",
7
+ examples: [
8
+ {
9
+ email: {
10
+ to: "user@example.com",
11
+ subject: "Welcome",
12
+ text: "Thanks for signing up."
13
+ },
14
+ discord: {
15
+ content: "A user signed up."
16
+ }
17
+ }
18
+ ]
19
+ });
20
+
21
+ class NotificationSendError extends Schema.TaggedErrorClass()("NotificationSendError", {
22
+ message: Schema.String,
23
+ channel: Schema.optional(Schema.String),
24
+ error: Schema.optional(Schema.Defect())
25
+ }) {
26
+ }
27
+ export {
28
+ NotificationSendError,
29
+ NotificationMessageSchema
30
+ };
@@ -0,0 +1,8 @@
1
+ import { Config, Effect, Layer, Context } from "effect";
2
+ declare const OpenTelemetry_base: Context.ServiceClass<OpenTelemetry, "OpenTelemetry", void> & {
3
+ readonly make: Effect.Effect<void, never, never>;
4
+ };
5
+ export declare class OpenTelemetry extends OpenTelemetry_base {
6
+ static readonly layer: Layer.Layer<OpenTelemetry, Config.ConfigError, never>;
7
+ }
8
+ export {};
@@ -0,0 +1,23 @@
1
+ // ../../src/services/opentelemetry.ts
2
+ import { FetchHttpClient } from "effect/unstable/http";
3
+ import { Otlp, OtlpSerialization } from "effect/unstable/observability";
4
+ import { Config, Effect, Layer, Context } from "effect";
5
+ var OtelLive = Layer.unwrap(Effect.gen(function* () {
6
+ const serviceName = yield* Config.string("OTEL_SERVICE_NAME").pipe(Config.withDefault("app"));
7
+ const otlpEndpoint = yield* Config.string("OTEL_EXPORTER_OTLP_ENDPOINT").pipe(Config.withDefault("http://localhost:4318"));
8
+ return Otlp.layer({
9
+ baseUrl: otlpEndpoint,
10
+ resource: {
11
+ serviceName
12
+ }
13
+ }).pipe(Layer.provide(OtlpSerialization.layerJson), Layer.provide(FetchHttpClient.layer));
14
+ }));
15
+
16
+ class OpenTelemetry extends Context.Service()("OpenTelemetry", {
17
+ make: Effect.log("OpenTelemetry initialized")
18
+ }) {
19
+ static layer = Layer.effect(this, this.make).pipe(Layer.provideMerge(OtelLive));
20
+ }
21
+ export {
22
+ OpenTelemetry
23
+ };
@@ -0,0 +1,62 @@
1
+ import { Config, Context, Effect, Layer } from "effect";
2
+ import { S3ServiceError } from "./schema.js";
3
+ declare const S3ServiceConfig_base: Context.ServiceClass<S3ServiceConfig, "S3ServiceConfig", {
4
+ options: {
5
+ accessKeyId: string;
6
+ secretAccessKey: string;
7
+ bucket: string;
8
+ region?: string | undefined;
9
+ endpoint?: string | undefined;
10
+ sessionToken?: string | undefined;
11
+ };
12
+ }> & {
13
+ readonly make: Effect.Effect<{
14
+ options: {
15
+ accessKeyId: string;
16
+ secretAccessKey: string;
17
+ bucket: string;
18
+ region?: string | undefined;
19
+ endpoint?: string | undefined;
20
+ sessionToken?: string | undefined;
21
+ };
22
+ }, Config.ConfigError, never>;
23
+ };
24
+ export declare class S3ServiceConfig extends S3ServiceConfig_base {
25
+ static readonly layer: Layer.Layer<S3ServiceConfig, Config.ConfigError, never>;
26
+ }
27
+ declare const S3Service_base: Context.ServiceClass<S3Service, "S3Service", {
28
+ file: (path: string, options?: Bun.S3Options | undefined) => Effect.Effect<Bun.S3File, S3ServiceError, never>;
29
+ write: (path: string, data: string | Bun.Archive | ArrayBuffer | Blob | Bun.BunFile | File | Request | Response | Bun.S3File | SharedArrayBuffer | Bun.ArrayBufferView<ArrayBufferLike>, options?: Bun.S3Options | undefined) => Effect.Effect<number, S3ServiceError, never>;
30
+ text: (path: string) => Effect.Effect<string, S3ServiceError, never>;
31
+ json: (path: string) => Effect.Effect<any, S3ServiceError, never>;
32
+ bytes: (path: string) => Effect.Effect<Uint8Array<ArrayBuffer>, S3ServiceError, never>;
33
+ arrayBuffer: (path: string) => Effect.Effect<ArrayBuffer, S3ServiceError, never>;
34
+ stream: (path: string) => Effect.Effect<ReadableStream<Uint8Array<ArrayBuffer>>, S3ServiceError, never>;
35
+ exists: (path: string) => Effect.Effect<boolean, S3ServiceError, never>;
36
+ stat: (path: string) => Effect.Effect<Bun.S3Stats, S3ServiceError, never>;
37
+ size: (path: string) => Effect.Effect<number, S3ServiceError, never>;
38
+ delete: (path: string) => Effect.Effect<void, S3ServiceError, never>;
39
+ presign: (path: string, options?: Bun.S3FilePresignOptions | undefined) => Effect.Effect<string, S3ServiceError, never>;
40
+ list: (options?: Bun.S3ListObjectsOptions | null | undefined) => Effect.Effect<Bun.S3ListObjectsResponse, S3ServiceError, never>;
41
+ }> & {
42
+ readonly make: Effect.Effect<{
43
+ file: (path: string, options?: Bun.S3Options | undefined) => Effect.Effect<Bun.S3File, S3ServiceError, never>;
44
+ write: (path: string, data: string | Bun.Archive | ArrayBuffer | Blob | Bun.BunFile | File | Request | Response | Bun.S3File | SharedArrayBuffer | Bun.ArrayBufferView<ArrayBufferLike>, options?: Bun.S3Options | undefined) => Effect.Effect<number, S3ServiceError, never>;
45
+ text: (path: string) => Effect.Effect<string, S3ServiceError, never>;
46
+ json: (path: string) => Effect.Effect<any, S3ServiceError, never>;
47
+ bytes: (path: string) => Effect.Effect<Uint8Array<ArrayBuffer>, S3ServiceError, never>;
48
+ arrayBuffer: (path: string) => Effect.Effect<ArrayBuffer, S3ServiceError, never>;
49
+ stream: (path: string) => Effect.Effect<ReadableStream<Uint8Array<ArrayBuffer>>, S3ServiceError, never>;
50
+ exists: (path: string) => Effect.Effect<boolean, S3ServiceError, never>;
51
+ stat: (path: string) => Effect.Effect<Bun.S3Stats, S3ServiceError, never>;
52
+ size: (path: string) => Effect.Effect<number, S3ServiceError, never>;
53
+ delete: (path: string) => Effect.Effect<void, S3ServiceError, never>;
54
+ presign: (path: string, options?: Bun.S3FilePresignOptions | undefined) => Effect.Effect<string, S3ServiceError, never>;
55
+ list: (options?: Bun.S3ListObjectsOptions | null | undefined) => Effect.Effect<Bun.S3ListObjectsResponse, S3ServiceError, never>;
56
+ }, never, S3ServiceConfig>;
57
+ };
58
+ export declare class S3Service extends S3Service_base {
59
+ static readonly layer: Layer.Layer<S3Service, Config.ConfigError, never>;
60
+ static readonly testLayer: (service: typeof this.Service) => Layer.Layer<S3Service, never, never>;
61
+ }
62
+ export {};