@interfere/react 0.1.0-alpha.4 → 0.1.0-alpha.6
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/client.d.mts +1 -8
- package/dist/client.d.mts.map +1 -1
- package/dist/client.mjs +5 -66
- package/dist/client.mjs.map +1 -1
- package/dist/core/events/define-event.d.mts +12 -0
- package/dist/core/events/define-event.d.mts.map +1 -0
- package/dist/core/events/define-event.mjs +39 -0
- package/dist/core/events/define-event.mjs.map +1 -0
- package/dist/core/events/event-registry.d.mts.map +1 -1
- package/dist/core/events/plugin-event-types.d.mts +43 -5
- package/dist/core/events/plugin-event-types.d.mts.map +1 -1
- package/dist/core/events/plugin-event-types.mjs.map +1 -1
- package/dist/core/plugins/define-plugin.d.mts +43 -0
- package/dist/core/plugins/define-plugin.d.mts.map +1 -0
- package/dist/core/plugins/define-plugin.mjs +23 -0
- package/dist/core/plugins/define-plugin.mjs.map +1 -0
- package/dist/core/plugins/dom-utils.d.mts.map +1 -1
- package/dist/core/plugins/impl/ai-summary/ai-summary-plugin-api.d.mts +18 -0
- package/dist/core/plugins/impl/ai-summary/ai-summary-plugin-api.d.mts.map +1 -0
- package/dist/core/plugins/impl/ai-summary/ai-summary-plugin-api.mjs +17 -0
- package/dist/core/plugins/impl/ai-summary/ai-summary-plugin-api.mjs.map +1 -0
- package/dist/core/plugins/impl/ai-summary/plugin.d.mts +6 -0
- package/dist/core/plugins/impl/ai-summary/plugin.d.mts.map +1 -0
- package/dist/core/plugins/impl/ai-summary/plugin.mjs +151 -0
- package/dist/core/plugins/impl/ai-summary/plugin.mjs.map +1 -0
- package/dist/core/plugins/impl/errors/errors-plugin-api.d.mts +17 -0
- package/dist/core/plugins/impl/errors/errors-plugin-api.d.mts.map +1 -0
- package/dist/core/plugins/impl/errors/errors-plugin-api.mjs +58 -0
- package/dist/core/plugins/impl/errors/errors-plugin-api.mjs.map +1 -0
- package/dist/core/plugins/impl/errors/logic.d.mts +15 -0
- package/dist/core/plugins/impl/errors/logic.d.mts.map +1 -0
- package/dist/core/plugins/impl/errors/logic.mjs +48 -0
- package/dist/core/plugins/impl/errors/logic.mjs.map +1 -0
- package/dist/core/plugins/impl/errors/patches.d.mts +13 -0
- package/dist/core/plugins/impl/errors/patches.d.mts.map +1 -0
- package/dist/core/plugins/impl/errors/patches.mjs +43 -0
- package/dist/core/plugins/impl/errors/patches.mjs.map +1 -0
- package/dist/core/plugins/impl/errors/plugin.d.mts +9 -0
- package/dist/core/plugins/impl/errors/plugin.d.mts.map +1 -0
- package/dist/core/plugins/impl/errors/plugin.mjs +91 -0
- package/dist/core/plugins/impl/errors/plugin.mjs.map +1 -0
- package/dist/core/plugins/impl/page-events/page-events-plugin-api.d.mts +19 -0
- package/dist/core/plugins/impl/page-events/page-events-plugin-api.d.mts.map +1 -0
- package/dist/core/plugins/impl/page-events/page-events-plugin-api.mjs +38 -0
- package/dist/core/plugins/impl/page-events/page-events-plugin-api.mjs.map +1 -0
- package/dist/core/plugins/impl/page-events/plugin.d.mts +6 -0
- package/dist/core/plugins/impl/page-events/plugin.d.mts.map +1 -0
- package/dist/core/plugins/impl/page-events/plugin.mjs +95 -0
- package/dist/core/plugins/impl/page-events/plugin.mjs.map +1 -0
- package/dist/core/plugins/impl/rage-click/plugin.d.mts +6 -0
- package/dist/core/plugins/impl/rage-click/plugin.d.mts.map +1 -0
- package/dist/core/plugins/impl/rage-click/plugin.mjs +38 -0
- package/dist/core/plugins/impl/rage-click/plugin.mjs.map +1 -0
- package/dist/core/plugins/impl/rage-click/rage-click.layer.d.mts +9 -0
- package/dist/core/plugins/impl/rage-click/rage-click.layer.d.mts.map +1 -0
- package/dist/core/plugins/impl/rage-click/rage-click.layer.mjs +35 -0
- package/dist/core/plugins/impl/rage-click/rage-click.layer.mjs.map +1 -0
- package/dist/core/plugins/impl/rage-click/rage-click.service.d.mts +16 -0
- package/dist/core/plugins/impl/rage-click/rage-click.service.d.mts.map +1 -0
- package/dist/core/plugins/impl/rage-click/rage-click.service.mjs +7 -0
- package/dist/core/plugins/impl/rage-click/rage-click.service.mjs.map +1 -0
- package/dist/core/plugins/impl/rage-click/rage-click.test-layer.d.mts +16 -0
- package/dist/core/plugins/impl/rage-click/rage-click.test-layer.d.mts.map +1 -0
- package/dist/core/plugins/impl/rage-click/rage-click.test-layer.mjs +18 -0
- package/dist/core/plugins/impl/rage-click/rage-click.test-layer.mjs.map +1 -0
- package/dist/core/plugins/impl/replay/plugin.d.mts +9 -0
- package/dist/core/plugins/impl/replay/plugin.d.mts.map +1 -0
- package/dist/core/plugins/impl/replay/plugin.mjs +83 -0
- package/dist/core/plugins/impl/replay/plugin.mjs.map +1 -0
- package/dist/core/plugins/impl/replay/replay-plugin-api.d.mts +18 -0
- package/dist/core/plugins/impl/replay/replay-plugin-api.d.mts.map +1 -0
- package/dist/core/plugins/impl/replay/replay-plugin-api.mjs +50 -0
- package/dist/core/plugins/impl/replay/replay-plugin-api.mjs.map +1 -0
- package/dist/core/plugins/impl/server-tracing/plugin.d.mts +13 -0
- package/dist/core/plugins/impl/server-tracing/plugin.d.mts.map +1 -0
- package/dist/core/plugins/impl/server-tracing/plugin.mjs +75 -0
- package/dist/core/plugins/impl/server-tracing/plugin.mjs.map +1 -0
- package/dist/core/plugins/impl/server-tracing/server-tracing-plugin-api.d.mts +16 -0
- package/dist/core/plugins/impl/server-tracing/server-tracing-plugin-api.d.mts.map +1 -0
- package/dist/core/plugins/impl/server-tracing/server-tracing-plugin-api.mjs +17 -0
- package/dist/core/plugins/impl/server-tracing/server-tracing-plugin-api.mjs.map +1 -0
- package/dist/core/plugins/impl/server-tracing/tracing-logic.d.mts +29 -0
- package/dist/core/plugins/impl/server-tracing/tracing-logic.d.mts.map +1 -0
- package/dist/core/plugins/impl/server-tracing/tracing-logic.mjs +55 -0
- package/dist/core/plugins/impl/server-tracing/tracing-logic.mjs.map +1 -0
- package/dist/core/plugins/plugin-loader.d.mts +68 -15
- package/dist/core/plugins/plugin-loader.d.mts.map +1 -1
- package/dist/core/plugins/plugin-loader.mjs +65 -128
- package/dist/core/plugins/plugin-loader.mjs.map +1 -1
- package/dist/core/plugins/services/event-capture.d.mts +12 -0
- package/dist/core/plugins/services/event-capture.d.mts.map +1 -0
- package/dist/core/plugins/services/event-capture.layer.d.mts +11 -0
- package/dist/core/plugins/services/event-capture.layer.d.mts.map +1 -0
- package/dist/core/plugins/services/event-capture.layer.mjs +79 -0
- package/dist/core/plugins/services/event-capture.layer.mjs.map +1 -0
- package/dist/core/plugins/services/event-capture.mjs +7 -0
- package/dist/core/plugins/services/event-capture.mjs.map +1 -0
- package/dist/core/plugins/services/event-capture.test-layer.d.mts +17 -0
- package/dist/core/plugins/services/event-capture.test-layer.d.mts.map +1 -0
- package/dist/core/plugins/services/event-capture.test-layer.mjs +21 -0
- package/dist/core/plugins/services/event-capture.test-layer.mjs.map +1 -0
- package/dist/core/plugins/services/plugin-config.d.mts +11 -0
- package/dist/core/plugins/services/plugin-config.d.mts.map +1 -0
- package/dist/core/plugins/services/plugin-config.mjs +7 -0
- package/dist/core/plugins/services/plugin-config.mjs.map +1 -0
- package/dist/core/plugins/services/plugin-config.test-layer.d.mts +60 -0
- package/dist/core/plugins/services/plugin-config.test-layer.d.mts.map +1 -0
- package/dist/core/plugins/services/plugin-config.test-layer.mjs +8 -0
- package/dist/core/plugins/services/plugin-config.test-layer.mjs.map +1 -0
- package/dist/core/plugins/services/plugin-logger.d.mts +14 -0
- package/dist/core/plugins/services/plugin-logger.d.mts.map +1 -0
- package/dist/core/plugins/services/plugin-logger.mjs +7 -0
- package/dist/core/plugins/services/plugin-logger.mjs.map +1 -0
- package/dist/core/plugins/services/plugin-logger.test-layer.d.mts +18 -0
- package/dist/core/plugins/services/plugin-logger.test-layer.d.mts.map +1 -0
- package/dist/core/plugins/services/plugin-logger.test-layer.mjs +28 -0
- package/dist/core/plugins/services/plugin-logger.test-layer.mjs.map +1 -0
- package/dist/core/plugins/services/plugin-runtime.d.mts +10 -0
- package/dist/core/plugins/services/plugin-runtime.d.mts.map +1 -0
- package/dist/core/plugins/services/plugin-runtime.mjs +7 -0
- package/dist/core/plugins/services/plugin-runtime.mjs.map +1 -0
- package/dist/core/plugins/services/plugin-runtime.test-layer.d.mts +16 -0
- package/dist/core/plugins/services/plugin-runtime.test-layer.d.mts.map +1 -0
- package/dist/core/plugins/services/plugin-runtime.test-layer.mjs +21 -0
- package/dist/core/plugins/services/plugin-runtime.test-layer.mjs.map +1 -0
- package/dist/core/plugins/services/session-info.d.mts +11 -0
- package/dist/core/plugins/services/session-info.d.mts.map +1 -0
- package/dist/core/plugins/services/session-info.mjs +7 -0
- package/dist/core/plugins/services/session-info.mjs.map +1 -0
- package/dist/core/plugins/services/session-info.test-layer.d.mts +18 -0
- package/dist/core/plugins/services/session-info.test-layer.d.mts.map +1 -0
- package/dist/core/plugins/services/session-info.test-layer.mjs +20 -0
- package/dist/core/plugins/services/session-info.test-layer.mjs.map +1 -0
- package/dist/core/runtime/config.d.mts +1 -1
- package/dist/core/runtime/config.d.mts.map +1 -1
- package/dist/core/runtime/config.mjs +3 -9
- package/dist/core/runtime/config.mjs.map +1 -1
- package/dist/core/runtime/context.d.mts +30 -5
- package/dist/core/runtime/context.d.mts.map +1 -1
- package/dist/core/runtime/context.mjs +15 -17
- package/dist/core/runtime/context.mjs.map +1 -1
- package/dist/core/runtime/ingest-target.d.mts +1 -1
- package/dist/core/runtime/ingest-target.d.mts.map +1 -1
- package/dist/core/runtime/ingest-target.mjs +1 -1
- package/dist/core/runtime/ingest-target.mjs.map +1 -1
- package/dist/core/runtime/native-fetch.d.mts +32 -0
- package/dist/core/runtime/native-fetch.d.mts.map +1 -0
- package/dist/core/runtime/native-fetch.mjs +49 -0
- package/dist/core/runtime/native-fetch.mjs.map +1 -0
- package/dist/core/schemas.d.mts +10 -69
- package/dist/core/schemas.d.mts.map +1 -1
- package/dist/effect/errors.d.mts +19 -33
- package/dist/effect/errors.d.mts.map +1 -1
- package/dist/effect/errors.mjs +13 -6
- package/dist/effect/errors.mjs.map +1 -1
- package/dist/effect/layers/circuit-breaker.layer.d.mts +9 -0
- package/dist/effect/layers/circuit-breaker.layer.d.mts.map +1 -0
- package/dist/effect/layers/circuit-breaker.layer.mjs +9 -0
- package/dist/effect/layers/circuit-breaker.layer.mjs.map +1 -0
- package/dist/effect/layers/circuit-breaker.layer.test-layer.d.mts +18 -0
- package/dist/effect/layers/circuit-breaker.layer.test-layer.d.mts.map +1 -0
- package/dist/effect/layers/circuit-breaker.layer.test-layer.mjs +43 -0
- package/dist/effect/layers/circuit-breaker.layer.test-layer.mjs.map +1 -0
- package/dist/effect/layers/config.layer.d.mts.map +1 -1
- package/dist/effect/layers/context.layer.d.mts.map +1 -1
- package/dist/effect/layers/context.layer.mjs.map +1 -1
- package/dist/effect/layers/http.layer.d.mts.map +1 -1
- package/dist/effect/layers/http.layer.mjs +15 -10
- package/dist/effect/layers/http.layer.mjs.map +1 -1
- package/dist/effect/layers/queue.layer.d.mts +8 -7
- package/dist/effect/layers/queue.layer.d.mts.map +1 -1
- package/dist/effect/layers/queue.layer.mjs +46 -47
- package/dist/effect/layers/queue.layer.mjs.map +1 -1
- package/dist/effect/layers/queue.layer.test-layer.d.mts +19 -0
- package/dist/effect/layers/queue.layer.test-layer.d.mts.map +1 -0
- package/dist/effect/layers/queue.layer.test-layer.mjs +44 -0
- package/dist/effect/layers/queue.layer.test-layer.mjs.map +1 -0
- package/dist/effect/layers/session.layer.d.mts +16 -8
- package/dist/effect/layers/session.layer.d.mts.map +1 -1
- package/dist/effect/layers/session.layer.mjs +10 -9
- package/dist/effect/layers/session.layer.mjs.map +1 -1
- package/dist/effect/layers/storage.layer.d.mts +5 -5
- package/dist/effect/layers/storage.layer.d.mts.map +1 -1
- package/dist/effect/layers/storage.layer.mjs +11 -11
- package/dist/effect/layers/storage.layer.mjs.map +1 -1
- package/dist/effect/layers/test-utils.d.mts +19 -0
- package/dist/effect/layers/test-utils.d.mts.map +1 -0
- package/dist/effect/layers/test-utils.mjs +32 -0
- package/dist/effect/layers/test-utils.mjs.map +1 -0
- package/dist/effect/runtime-services.d.mts +5 -4
- package/dist/effect/runtime-services.d.mts.map +1 -1
- package/dist/effect/runtime-services.mjs +9 -6
- package/dist/effect/runtime-services.mjs.map +1 -1
- package/dist/effect/tags.d.mts.map +1 -1
- package/dist/hooks/use-runtime-and-plugins.d.mts +2 -2
- package/dist/hooks/use-runtime-and-plugins.d.mts.map +1 -1
- package/dist/hooks/use-runtime-and-plugins.mjs +13 -45
- package/dist/hooks/use-runtime-and-plugins.mjs.map +1 -1
- package/dist/hooks/use-session.d.mts.map +1 -1
- package/dist/package.mjs +8 -5
- package/dist/provider.d.mts +1 -1
- package/dist/provider.d.mts.map +1 -1
- package/dist/provider.mjs.map +1 -1
- package/dist/server/auth.d.mts +6 -2
- package/dist/server/auth.d.mts.map +1 -1
- package/dist/server/auth.mjs +22 -13
- package/dist/server/auth.mjs.map +1 -1
- package/dist/server/capture.d.mts +18 -2
- package/dist/server/capture.d.mts.map +1 -1
- package/dist/server/capture.mjs +77 -10
- package/dist/server/capture.mjs.map +1 -1
- package/package.json +37 -34
- package/dist/core/plugins/impl/ai-summary.d.mts +0 -6
- package/dist/core/plugins/impl/ai-summary.d.mts.map +0 -1
- package/dist/core/plugins/impl/ai-summary.mjs +0 -122
- package/dist/core/plugins/impl/ai-summary.mjs.map +0 -1
- package/dist/core/plugins/impl/errors.d.mts +0 -9
- package/dist/core/plugins/impl/errors.d.mts.map +0 -1
- package/dist/core/plugins/impl/errors.mjs +0 -153
- package/dist/core/plugins/impl/errors.mjs.map +0 -1
- package/dist/core/plugins/impl/page-events.d.mts +0 -15
- package/dist/core/plugins/impl/page-events.d.mts.map +0 -1
- package/dist/core/plugins/impl/page-events.mjs +0 -131
- package/dist/core/plugins/impl/page-events.mjs.map +0 -1
- package/dist/core/plugins/impl/rage-click.d.mts +0 -6
- package/dist/core/plugins/impl/rage-click.d.mts.map +0 -1
- package/dist/core/plugins/impl/rage-click.mjs +0 -53
- package/dist/core/plugins/impl/rage-click.mjs.map +0 -1
- package/dist/core/plugins/impl/replay.d.mts +0 -9
- package/dist/core/plugins/impl/replay.d.mts.map +0 -1
- package/dist/core/plugins/impl/replay.mjs +0 -144
- package/dist/core/plugins/impl/replay.mjs.map +0 -1
- package/dist/core/plugins/impl/server-tracing.d.mts +0 -7
- package/dist/core/plugins/impl/server-tracing.d.mts.map +0 -1
- package/dist/core/plugins/impl/server-tracing.mjs +0 -160
- package/dist/core/plugins/impl/server-tracing.mjs.map +0 -1
- package/dist/core/plugins/plugin-event-system.d.mts +0 -47
- package/dist/core/plugins/plugin-event-system.d.mts.map +0 -1
- package/dist/core/plugins/plugin-event-system.mjs +0 -75
- package/dist/core/plugins/plugin-event-system.mjs.map +0 -1
- package/dist/effect/build-envelope.d.mts +0 -9
- package/dist/effect/build-envelope.d.mts.map +0 -1
- package/dist/effect/build-envelope.mjs +0 -29
- package/dist/effect/build-envelope.mjs.map +0 -1
- package/dist/effect/layers/tracer.layer.d.mts +0 -9
- package/dist/effect/layers/tracer.layer.d.mts.map +0 -1
- package/dist/effect/layers/tracer.layer.mjs +0 -11
- package/dist/effect/layers/tracer.layer.mjs.map +0 -1
package/dist/client.d.mts
CHANGED
|
@@ -1,15 +1,8 @@
|
|
|
1
|
-
import { SessionServiceTag } from "./effect/layers/session.layer.mjs";
|
|
2
|
-
import { ConfigTag } from "./effect/tags.mjs";
|
|
3
1
|
import { EventPayload } from "./core/events/event-registry.mjs";
|
|
4
|
-
import { ValidationError } from "./effect/errors.mjs";
|
|
5
|
-
import { ContextServiceTag } from "./effect/layers/context.layer.mjs";
|
|
6
|
-
import { QueueServiceTag } from "./effect/layers/queue.layer.mjs";
|
|
7
|
-
import { Effect } from "effect";
|
|
8
2
|
import { EventType } from "@interfere/types/sdk/plugins/lib/types";
|
|
9
3
|
|
|
10
4
|
//#region src/client.d.ts
|
|
11
5
|
type CaptureFn = <T extends EventType>(type: T, payload: EventPayload<T>) => void;
|
|
12
|
-
declare function captureEffect<T extends EventType>(type: T, payload: EventPayload<T>): Effect.Effect<void, ValidationError, QueueServiceTag | SessionServiceTag | ConfigTag | ContextServiceTag>;
|
|
13
6
|
declare const capture: CaptureFn;
|
|
14
7
|
//#endregion
|
|
15
|
-
export { CaptureFn, capture
|
|
8
|
+
export { CaptureFn, capture };
|
package/dist/client.d.mts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.d.mts","names":[],"sources":["../src/client.ts"],"
|
|
1
|
+
{"version":3,"file":"client.d.mts","names":[],"sources":["../src/client.ts"],"mappings":";;;;KAQY,SAAA,cAAuB,SAAA,EACjC,IAAA,EAAM,CAAA,EACN,OAAA,EAAS,YAAA,CAAa,CAAA;AAAA,cAGX,OAAA,EAAS,SAAA"}
|
package/dist/client.mjs
CHANGED
|
@@ -1,75 +1,14 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { buildEnvelopeEffect } from "./effect/build-envelope.mjs";
|
|
3
|
-
import { ValidationError } from "./effect/errors.mjs";
|
|
4
|
-
import { ContextServiceTag } from "./effect/layers/context.layer.mjs";
|
|
5
|
-
import { QueueServiceTag } from "./effect/layers/queue.layer.mjs";
|
|
6
|
-
import { withSpan } from "./effect/layers/tracer.layer.mjs";
|
|
1
|
+
import { EventCapture } from "./core/plugins/services/event-capture.mjs";
|
|
7
2
|
import { forkWithSDK } from "./effect/runtime-services.mjs";
|
|
8
3
|
import { Effect } from "effect";
|
|
9
4
|
|
|
10
5
|
//#region src/client.ts
|
|
11
|
-
function enrichPayload(basePayload, properties) {
|
|
12
|
-
if (typeof basePayload === "object" && basePayload !== null) {
|
|
13
|
-
const merged = {
|
|
14
|
-
...basePayload.properties ?? {},
|
|
15
|
-
...properties
|
|
16
|
-
};
|
|
17
|
-
return {
|
|
18
|
-
...basePayload,
|
|
19
|
-
properties: merged
|
|
20
|
-
};
|
|
21
|
-
}
|
|
22
|
-
return { properties };
|
|
23
|
-
}
|
|
24
|
-
function captureEffect(type, payload) {
|
|
25
|
-
const handler = dynamicRegistry.get(type);
|
|
26
|
-
if (!handler) return Effect.gen(function* () {
|
|
27
|
-
const queue = yield* QueueServiceTag;
|
|
28
|
-
const env = yield* buildEnvelopeEffect({
|
|
29
|
-
type,
|
|
30
|
-
payload
|
|
31
|
-
});
|
|
32
|
-
yield* queue.add(env);
|
|
33
|
-
yield* Effect.logTrace("Captured event with no handler", {
|
|
34
|
-
type,
|
|
35
|
-
envelopeId: env.uuid,
|
|
36
|
-
path: "fast"
|
|
37
|
-
});
|
|
38
|
-
}).pipe(Effect.withSpan("capture.fast", { attributes: { type } }));
|
|
39
|
-
return Effect.gen(function* () {
|
|
40
|
-
const queue = yield* QueueServiceTag;
|
|
41
|
-
const context = yield* ContextServiceTag;
|
|
42
|
-
const validated = yield* withSpan("capture.validate", Effect.sync(() => handler ? handler.schema.safeParse(payload) : {
|
|
43
|
-
success: false,
|
|
44
|
-
error: { issues: [{ message: "Missing handler" }] }
|
|
45
|
-
}).pipe(Effect.flatMap((result) => result.success === true ? Effect.succeed(result.data) : Effect.fail(new ValidationError({
|
|
46
|
-
message: "Invalid payload",
|
|
47
|
-
payload,
|
|
48
|
-
issues: result.error?.issues
|
|
49
|
-
})))), { attributes: { type } });
|
|
50
|
-
const transformed = handler && "transform" in handler && typeof handler.transform === "function" ? handler.transform(validated) : validated;
|
|
51
|
-
const env = yield* buildEnvelopeEffect({
|
|
52
|
-
type,
|
|
53
|
-
payload: handler?.enrich === true ? yield* withSpan("capture.enrich", context.getOnce().pipe(Effect.map((properties) => enrichPayload(transformed, properties))), { attributes: { type } }) : transformed
|
|
54
|
-
});
|
|
55
|
-
yield* queue.add(env);
|
|
56
|
-
yield* Effect.logTrace("Captured event with handler", {
|
|
57
|
-
type,
|
|
58
|
-
envelopeId: env.uuid
|
|
59
|
-
});
|
|
60
|
-
}).pipe(Effect.withSpan("capture.full", { attributes: { type } }));
|
|
61
|
-
}
|
|
62
6
|
const capture = (type, payload) => {
|
|
63
7
|
if (typeof window === "undefined") return;
|
|
64
|
-
forkWithSDK(
|
|
65
|
-
type,
|
|
66
|
-
|
|
67
|
-
issues: err.issues
|
|
68
|
-
})), Effect.catchAll((err) => Effect.logError("Failed to capture event", {
|
|
69
|
-
type,
|
|
70
|
-
error: String(err)
|
|
71
|
-
}))));
|
|
8
|
+
forkWithSDK(Effect.gen(function* () {
|
|
9
|
+
yield* (yield* EventCapture).capture(type, payload);
|
|
10
|
+
}).pipe(Effect.withSpan("capture")));
|
|
72
11
|
};
|
|
73
12
|
|
|
74
13
|
//#endregion
|
|
75
|
-
export { capture
|
|
14
|
+
export { capture };
|
package/dist/client.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.mjs","names":[
|
|
1
|
+
{"version":3,"file":"client.mjs","names":[],"sources":["../src/client.ts"],"sourcesContent":["import type { EventType } from \"@interfere/types/sdk/plugins/lib/types\";\n\nimport { Effect } from \"effect\";\n\nimport type { EventPayload } from \"./core/events/event-registry.js\";\nimport { EventCapture } from \"./core/plugins/services/event-capture.js\";\nimport { forkWithSDK } from \"./effect/runtime-services.js\";\n\nexport type CaptureFn = <T extends EventType>(\n type: T,\n payload: EventPayload<T>\n) => void;\n\nexport const capture: CaptureFn = <T extends EventType>(\n type: T,\n payload: EventPayload<T>\n) => {\n if (typeof window === \"undefined\") {\n return;\n }\n\n forkWithSDK(\n Effect.gen(function* () {\n const eventCapture = yield* EventCapture;\n yield* eventCapture.capture(type, payload);\n }).pipe(Effect.withSpan(\"capture\"))\n );\n};\n"],"mappings":";;;;;AAaA,MAAa,WACX,MACA,YACG;AACH,KAAI,OAAO,WAAW,YACpB;AAGF,aACE,OAAO,IAAI,aAAa;AAEtB,UADqB,OAAO,cACR,QAAQ,MAAM,QAAQ;GAC1C,CAAC,KAAK,OAAO,SAAS,UAAU,CAAC,CACpC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { EventDefinitionFor, EventSchemas } from "./plugin-event-types.mjs";
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
|
|
4
|
+
//#region src/core/events/define-event.d.ts
|
|
5
|
+
type FinalEventDefinition<T extends keyof EventSchemas> = EventDefinitionFor<T>;
|
|
6
|
+
declare function defineEvent<T extends keyof EventSchemas>(type: T): {
|
|
7
|
+
enrich: (v?: boolean) => EventDefinitionFor<T>;
|
|
8
|
+
transform: <TOut>(fn: (input: z.infer<EventSchemas[T]>) => TOut) => EventDefinitionFor<T>;
|
|
9
|
+
value: () => EventDefinitionFor<T>;
|
|
10
|
+
};
|
|
11
|
+
//#endregion
|
|
12
|
+
export { FinalEventDefinition, defineEvent };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"define-event.d.mts","names":[],"sources":["../../../src/core/events/define-event.ts"],"mappings":";;;;KAKY,oBAAA,iBAAqC,YAAA,IAC/C,kBAAA,CAAmB,CAAA;AAAA,iBA+BL,WAAA,iBAA4B,YAAA,CAAA,CAAc,IAAA,EAAM,CAAA;2BAIxC,kBAAA,CAAA,CAAA;oBACJ,EAAA,GAAO,KAAA,EAAO,CAAA,CAAE,KAAA,CAAM,YAAA,CAAa,CAAA,OAAQ,IAAA,KAAI,kBAAA,CAAA,CAAA"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { eventConfigs, eventSchemas } from "./plugin-event-types.mjs";
|
|
2
|
+
|
|
3
|
+
//#region src/core/events/define-event.ts
|
|
4
|
+
var FinalEventDefBuilder = class {
|
|
5
|
+
def;
|
|
6
|
+
constructor(type) {
|
|
7
|
+
this.def = {
|
|
8
|
+
type,
|
|
9
|
+
schema: eventSchemas[type],
|
|
10
|
+
enrich: eventConfigs[type].enrich
|
|
11
|
+
};
|
|
12
|
+
}
|
|
13
|
+
enrich(value = true) {
|
|
14
|
+
return {
|
|
15
|
+
...this.def,
|
|
16
|
+
enrich: value
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
transform(fn) {
|
|
20
|
+
return {
|
|
21
|
+
...this.def,
|
|
22
|
+
transform: fn
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
value() {
|
|
26
|
+
return { ...this.def };
|
|
27
|
+
}
|
|
28
|
+
};
|
|
29
|
+
function defineEvent(type) {
|
|
30
|
+
const builder = new FinalEventDefBuilder(type);
|
|
31
|
+
return {
|
|
32
|
+
enrich: (v) => builder.enrich(v ?? true),
|
|
33
|
+
transform: (fn) => builder.transform(fn),
|
|
34
|
+
value: () => builder.value()
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
//#endregion
|
|
39
|
+
export { defineEvent };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"define-event.mjs","names":[],"sources":["../../../src/core/events/define-event.ts"],"sourcesContent":["import type { z } from \"zod\";\n\nimport type { EventDefinitionFor, EventSchemas } from \"./plugin-event-types.js\";\nimport { eventConfigs, eventSchemas } from \"./plugin-event-types.js\";\n\nexport type FinalEventDefinition<T extends keyof EventSchemas> =\n EventDefinitionFor<T>;\n\nclass FinalEventDefBuilder<T extends keyof EventSchemas> {\n private readonly def: FinalEventDefinition<T>;\n\n constructor(type: T) {\n this.def = {\n type,\n schema: eventSchemas[type],\n enrich: eventConfigs[type].enrich,\n } as FinalEventDefinition<T>;\n }\n\n enrich(value = true): FinalEventDefinition<T> {\n return { ...this.def, enrich: value } as FinalEventDefinition<T>;\n }\n\n transform<TOut>(\n fn: (input: z.infer<EventSchemas[T]>) => TOut\n ): FinalEventDefinition<T> {\n return {\n ...this.def,\n transform: fn as (i: unknown) => unknown,\n } as FinalEventDefinition<T>;\n }\n\n value(): FinalEventDefinition<T> {\n return { ...this.def } as FinalEventDefinition<T>;\n }\n}\n\nexport function defineEvent<T extends keyof EventSchemas>(type: T) {\n const builder = new FinalEventDefBuilder(type);\n\n return {\n enrich: (v?: boolean) => builder.enrich(v ?? true),\n transform: <TOut>(fn: (input: z.infer<EventSchemas[T]>) => TOut) =>\n builder.transform(fn),\n value: () => builder.value(),\n };\n}\n"],"mappings":";;;AAQA,IAAM,uBAAN,MAAyD;CACvD,AAAiB;CAEjB,YAAY,MAAS;AACnB,OAAK,MAAM;GACT;GACA,QAAQ,aAAa;GACrB,QAAQ,aAAa,MAAM;GAC5B;;CAGH,OAAO,QAAQ,MAA+B;AAC5C,SAAO;GAAE,GAAG,KAAK;GAAK,QAAQ;GAAO;;CAGvC,UACE,IACyB;AACzB,SAAO;GACL,GAAG,KAAK;GACR,WAAW;GACZ;;CAGH,QAAiC;AAC/B,SAAO,EAAE,GAAG,KAAK,KAAK;;;AAI1B,SAAgB,YAA0C,MAAS;CACjE,MAAM,UAAU,IAAI,qBAAqB,KAAK;AAE9C,QAAO;EACL,SAAS,MAAgB,QAAQ,OAAO,KAAK,KAAK;EAClD,YAAkB,OAChB,QAAQ,UAAU,GAAG;EACvB,aAAa,QAAQ,OAAO;EAC7B"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"event-registry.d.mts","names":[],"sources":["../../../src/core/events/event-registry.ts"],"
|
|
1
|
+
{"version":3,"file":"event-registry.d.mts","names":[],"sources":["../../../src/core/events/event-registry.ts"],"mappings":";;;;;KAYY,eAAA,WAA0B,SAAA,IAAa,CAAA,eAAgB,YAAA,GAC/D,kBAAA,CAAmB,YAAA,CAAa,CAAA;AAAA,KAIxB,YAAA,WAAuB,SAAA,IAAa,CAAA,eAAgB,YAAA,GAC5D,CAAA,CAAE,KAAA,CAAM,YAAA,CAAa,CAAA;AAAA,iBAIT,eAAA,WAA0B,SAAA,CAAA,CACxC,IAAA,EAAM,CAAA,GACL,eAAA,CAAgB,CAAA;AAAA,iBAMH,eAAA,CAAgB,IAAA,EAAM,SAAA,GAAY,IAAA,UAAc,YAAA;AAAA,UAK/C,kBAAA,WAA6B,SAAA,GAAY,SAAA;EACxD,SAAA,EAAW,CAAA;EACX,OAAA,EAAS,eAAA,CAAgB,CAAA;AAAA;AAAA,cAId,oBAAA;EAAA,iBACM,eAAA;EAKjB,QAAA,WAAmB,SAAA,CAAA,CACjB,SAAA,EAAW,CAAA,EACX,OAAA,EAAS,eAAA,CAAgB,CAAA;EAQ3B,kBAAA,CAAmB,GAAA,EAAK,kBAAA;EAQxB,GAAA,WAAc,SAAA,CAAA,CAAW,SAAA,EAAW,CAAA,GAAI,eAAA,CAAgB,CAAA;EAOxD,KAAA,CAAM,QAAA,EAAU,kBAAA;AAAA;AAAA,cAQL,eAAA,EAAe,oBAAA"}
|
|
@@ -4,8 +4,8 @@ import { z } from "zod";
|
|
|
4
4
|
|
|
5
5
|
//#region src/core/events/plugin-event-types.d.ts
|
|
6
6
|
type PluginRegistrationInManifest = PluginManifest[number];
|
|
7
|
-
type EventsForPlugin<K
|
|
8
|
-
name: K
|
|
7
|
+
type EventsForPlugin<K extends PluginKey> = Extract<PluginRegistrationInManifest, {
|
|
8
|
+
name: K;
|
|
9
9
|
}>["events"][number]["name"];
|
|
10
10
|
declare const eventSchemas: {
|
|
11
11
|
readonly error: z.ZodObject<{
|
|
@@ -31,6 +31,42 @@ declare const eventSchemas: {
|
|
|
31
31
|
server: "server";
|
|
32
32
|
edge: "edge";
|
|
33
33
|
}>;
|
|
34
|
+
mechanism: z.ZodOptional<z.ZodObject<{
|
|
35
|
+
type: z.ZodString;
|
|
36
|
+
handled: z.ZodBoolean;
|
|
37
|
+
synthetic: z.ZodOptional<z.ZodBoolean>;
|
|
38
|
+
}, z.core.$strip>>;
|
|
39
|
+
nextjs: z.ZodOptional<z.ZodObject<{
|
|
40
|
+
routerKind: z.ZodOptional<z.ZodEnum<{
|
|
41
|
+
"Pages Router": "Pages Router";
|
|
42
|
+
"App Router": "App Router";
|
|
43
|
+
}>>;
|
|
44
|
+
routePath: z.ZodOptional<z.ZodString>;
|
|
45
|
+
routeType: z.ZodOptional<z.ZodEnum<{
|
|
46
|
+
render: "render";
|
|
47
|
+
route: "route";
|
|
48
|
+
action: "action";
|
|
49
|
+
middleware: "middleware";
|
|
50
|
+
proxy: "proxy";
|
|
51
|
+
}>>;
|
|
52
|
+
renderSource: z.ZodOptional<z.ZodEnum<{
|
|
53
|
+
"react-server-components": "react-server-components";
|
|
54
|
+
"react-server-components-payload": "react-server-components-payload";
|
|
55
|
+
"server-rendering": "server-rendering";
|
|
56
|
+
}>>;
|
|
57
|
+
revalidateReason: z.ZodOptional<z.ZodEnum<{
|
|
58
|
+
"on-demand": "on-demand";
|
|
59
|
+
stale: "stale";
|
|
60
|
+
}>>;
|
|
61
|
+
renderType: z.ZodOptional<z.ZodEnum<{
|
|
62
|
+
dynamic: "dynamic";
|
|
63
|
+
"dynamic-resume": "dynamic-resume";
|
|
64
|
+
}>>;
|
|
65
|
+
requestPath: z.ZodOptional<z.ZodString>;
|
|
66
|
+
requestMethod: z.ZodOptional<z.ZodString>;
|
|
67
|
+
errorDigest: z.ZodOptional<z.ZodString>;
|
|
68
|
+
}, z.core.$strip>>;
|
|
69
|
+
captureSource: z.ZodOptional<z.ZodString>;
|
|
34
70
|
}, z.core.$strip>;
|
|
35
71
|
readonly rage_click: z.ZodObject<{
|
|
36
72
|
count: z.ZodNumber;
|
|
@@ -48,6 +84,8 @@ declare const eventSchemas: {
|
|
|
48
84
|
ts: z.ZodNumber;
|
|
49
85
|
count: z.ZodNumber;
|
|
50
86
|
events: z.ZodArray<z.ZodString>;
|
|
87
|
+
first_event_ts: z.ZodOptional<z.ZodNumber>;
|
|
88
|
+
last_event_ts: z.ZodOptional<z.ZodNumber>;
|
|
51
89
|
}, z.core.$strip>;
|
|
52
90
|
readonly session_summary: z.ZodObject<{
|
|
53
91
|
summary: z.ZodString;
|
|
@@ -66,7 +104,7 @@ declare const eventSchemas: {
|
|
|
66
104
|
}, z.core.$strip>;
|
|
67
105
|
};
|
|
68
106
|
/** Per-event configuration derived from PLUGIN_MANIFEST. */
|
|
69
|
-
declare const eventConfigs: Record<"error" | "
|
|
107
|
+
declare const eventConfigs: Record<"error" | "rage_click" | "ui_event" | "replay_chunk" | "session_summary" | "pageview" | "pageleave", {
|
|
70
108
|
enrich: boolean;
|
|
71
109
|
}>;
|
|
72
110
|
type EventSchemas = typeof eventSchemas;
|
|
@@ -82,10 +120,10 @@ type EventDefinitionFor<T extends EventType> = T extends keyof EventSchemas ? {
|
|
|
82
120
|
enrich?: boolean;
|
|
83
121
|
transform?: (input: z.infer<EventSchemas[T]>) => unknown;
|
|
84
122
|
} : never;
|
|
85
|
-
type ValidatePluginEvents<K
|
|
123
|
+
type ValidatePluginEvents<K extends PluginKey, Events extends readonly AnyEventDefinition[]> = Events extends readonly (infer E)[] ? E extends AnyEventDefinition ? E["type"] extends EventsForPlugin<K> ? Events : never : never : never;
|
|
86
124
|
interface EventHandlerConfig<TSchema extends z.ZodType<unknown>, TInput = z.infer<TSchema>, TOutput = TInput> {
|
|
87
|
-
schema: TSchema;
|
|
88
125
|
enrich: boolean;
|
|
126
|
+
schema: TSchema;
|
|
89
127
|
transform?: (input: TInput) => TOutput;
|
|
90
128
|
}
|
|
91
129
|
//#endregion
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"plugin-event-types.d.mts","names":[],"sources":["../../../src/core/events/plugin-event-types.ts"],"
|
|
1
|
+
{"version":3,"file":"plugin-event-types.d.mts","names":[],"sources":["../../../src/core/events/plugin-event-types.ts"],"mappings":";;;;;KAoBK,4BAAA,GAA+B,cAAA;AAAA,KAExB,eAAA,WAA0B,SAAA,IAAa,OAAA,CACjD,4BAAA;EACE,IAAA,EAAM,CAAA;AAAA;AAAA,cAIG,YAAA;EAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;cAWA,YAAA,EAAY,MAAA;EAAA,MAAA;AAAA;AAAA,KAUb,YAAA,UAAsB,YAAA;AAAA,KAGtB,kBAAA,iBACE,YAAA;EACV,IAAA,EAAM,CAAA;EACN,MAAA,EAAQ,YAAA,CAAa,CAAA;EACrB,MAAA;EACA,SAAA,IAAa,KAAA,EAAO,CAAA,CAAE,KAAA,CAAM,YAAA,CAAa,CAAA;AAAA,UAErC,YAAA;AAAA,KAGI,kBAAA,WAA6B,SAAA,IACvC,CAAA,eAAgB,YAAA;EAEV,IAAA,EAAM,CAAA;EACN,MAAA,EAAQ,YAAA,CAAa,CAAA;EACrB,MAAA;EACA,SAAA,IAAa,KAAA,EAAO,CAAA,CAAE,KAAA,CAAM,YAAA,CAAa,CAAA;AAAA;AAAA,KAKrC,oBAAA,WACA,SAAA,0BACc,kBAAA,MACtB,MAAA,gCACA,CAAA,SAAU,kBAAA,GACR,CAAA,iBAAkB,eAAA,CAAgB,CAAA,IAChC,MAAA;AAAA,UAMS,kBAAA,iBACC,CAAA,CAAE,OAAA,oBACT,CAAA,CAAE,KAAA,CAAM,OAAA,aACP,MAAA;EAEV,MAAA;EACA,MAAA,EAAQ,OAAA;EACR,SAAA,IAAa,KAAA,EAAO,MAAA,KAAW,OAAA;AAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"plugin-event-types.mjs","names":[],"sources":["../../../src/core/events/plugin-event-types.ts"],"sourcesContent":["import type {\n EventType,\n PluginKey,\n} from \"@interfere/types/sdk/plugins/lib/types\";\nimport {\n PLUGIN_MANIFEST,\n type PluginManifest,\n} from \"@interfere/types/sdk/plugins/manifest\";\nimport { sessionSummaryPayloadSchema } from \"@interfere/types/sdk/plugins/payload/ai-summary\";\nimport { errorEnvelopePayloadSchema } from \"@interfere/types/sdk/plugins/payload/errors\";\nimport {\n pageleavePayloadSchema,\n pageviewPayloadSchema,\n uiEventPayloadSchema,\n} from \"@interfere/types/sdk/plugins/payload/page-events\";\nimport { rageClickPayloadSchema } from \"@interfere/types/sdk/plugins/payload/rage-click\";\nimport { replayChunkPayloadSchema } from \"@interfere/types/sdk/plugins/payload/replay\";\n\nimport type { z } from \"zod\";\n\ntype PluginRegistrationInManifest = PluginManifest[number];\n\nexport type EventsForPlugin<K extends PluginKey> = Extract<\n PluginRegistrationInManifest,\n { name: K }\n>[\"events\"][number][\"name\"];\n\n// Define the canonical event schemas and configurations\nexport const eventSchemas = {\n error: errorEnvelopePayloadSchema,\n rage_click: rageClickPayloadSchema,\n ui_event: uiEventPayloadSchema,\n replay_chunk: replayChunkPayloadSchema,\n session_summary: sessionSummaryPayloadSchema,\n pageview: pageviewPayloadSchema,\n pageleave: pageleavePayloadSchema,\n} as const;\n\n/** Per-event configuration derived from PLUGIN_MANIFEST. */\nexport const eventConfigs = PLUGIN_MANIFEST.reduce(\n (acc, plugin) => {\n for (const event of plugin.events) {\n acc[event.name as EventType] = { enrich: event.enrich };\n }\n return acc;\n },\n {} as Record<EventType, { enrich: boolean }>\n);\n\nexport type EventSchemas = typeof eventSchemas;\n\n// Discriminated union for all possible event definitions\nexport type AnyEventDefinition = {\n [K in keyof EventSchemas]: {\n type: K;\n schema: EventSchemas[K];\n enrich?: boolean;\n transform?: (input: z.infer<EventSchemas[K]>) => unknown;\n };\n}[keyof EventSchemas];\n\n// Strongly typed event definition for a specific event type\nexport type EventDefinitionFor<T extends EventType> =\n T extends keyof EventSchemas\n ? {\n type: T;\n schema: EventSchemas[T];\n enrich?: boolean;\n transform?: (input: z.infer<EventSchemas[T]>) => unknown;\n }\n : never;\n\n// Helper to validate that an array of event definitions matches a plugin's allowed events\nexport type ValidatePluginEvents<\n K extends PluginKey,\n Events extends readonly AnyEventDefinition[],\n> = Events extends readonly (infer E)[]\n ? E extends AnyEventDefinition\n ? E[\"type\"] extends EventsForPlugin<K>\n ? Events\n : never\n : never\n : never;\n\n// Type-safe event handler configuration\nexport interface EventHandlerConfig<\n TSchema extends z.ZodType<unknown>,\n TInput = z.infer<TSchema>,\n TOutput = TInput,\n> {\n
|
|
1
|
+
{"version":3,"file":"plugin-event-types.mjs","names":[],"sources":["../../../src/core/events/plugin-event-types.ts"],"sourcesContent":["import type {\n EventType,\n PluginKey,\n} from \"@interfere/types/sdk/plugins/lib/types\";\nimport {\n PLUGIN_MANIFEST,\n type PluginManifest,\n} from \"@interfere/types/sdk/plugins/manifest\";\nimport { sessionSummaryPayloadSchema } from \"@interfere/types/sdk/plugins/payload/ai-summary\";\nimport { errorEnvelopePayloadSchema } from \"@interfere/types/sdk/plugins/payload/errors\";\nimport {\n pageleavePayloadSchema,\n pageviewPayloadSchema,\n uiEventPayloadSchema,\n} from \"@interfere/types/sdk/plugins/payload/page-events\";\nimport { rageClickPayloadSchema } from \"@interfere/types/sdk/plugins/payload/rage-click\";\nimport { replayChunkPayloadSchema } from \"@interfere/types/sdk/plugins/payload/replay\";\n\nimport type { z } from \"zod\";\n\ntype PluginRegistrationInManifest = PluginManifest[number];\n\nexport type EventsForPlugin<K extends PluginKey> = Extract<\n PluginRegistrationInManifest,\n { name: K }\n>[\"events\"][number][\"name\"];\n\n// Define the canonical event schemas and configurations\nexport const eventSchemas = {\n error: errorEnvelopePayloadSchema,\n rage_click: rageClickPayloadSchema,\n ui_event: uiEventPayloadSchema,\n replay_chunk: replayChunkPayloadSchema,\n session_summary: sessionSummaryPayloadSchema,\n pageview: pageviewPayloadSchema,\n pageleave: pageleavePayloadSchema,\n} as const;\n\n/** Per-event configuration derived from PLUGIN_MANIFEST. */\nexport const eventConfigs = PLUGIN_MANIFEST.reduce(\n (acc, plugin) => {\n for (const event of plugin.events) {\n acc[event.name as EventType] = { enrich: event.enrich };\n }\n return acc;\n },\n {} as Record<EventType, { enrich: boolean }>\n);\n\nexport type EventSchemas = typeof eventSchemas;\n\n// Discriminated union for all possible event definitions\nexport type AnyEventDefinition = {\n [K in keyof EventSchemas]: {\n type: K;\n schema: EventSchemas[K];\n enrich?: boolean;\n transform?: (input: z.infer<EventSchemas[K]>) => unknown;\n };\n}[keyof EventSchemas];\n\n// Strongly typed event definition for a specific event type\nexport type EventDefinitionFor<T extends EventType> =\n T extends keyof EventSchemas\n ? {\n type: T;\n schema: EventSchemas[T];\n enrich?: boolean;\n transform?: (input: z.infer<EventSchemas[T]>) => unknown;\n }\n : never;\n\n// Helper to validate that an array of event definitions matches a plugin's allowed events\nexport type ValidatePluginEvents<\n K extends PluginKey,\n Events extends readonly AnyEventDefinition[],\n> = Events extends readonly (infer E)[]\n ? E extends AnyEventDefinition\n ? E[\"type\"] extends EventsForPlugin<K>\n ? Events\n : never\n : never\n : never;\n\n// Type-safe event handler configuration\nexport interface EventHandlerConfig<\n TSchema extends z.ZodType<unknown>,\n TInput = z.infer<TSchema>,\n TOutput = TInput,\n> {\n enrich: boolean;\n schema: TSchema;\n transform?: (input: TInput) => TOutput;\n}\n"],"mappings":";;;;;;;;AA4BA,MAAa,eAAe;CAC1B,OAAO;CACP,YAAY;CACZ,UAAU;CACV,cAAc;CACd,iBAAiB;CACjB,UAAU;CACV,WAAW;CACZ;;AAGD,MAAa,eAAe,gBAAgB,QACzC,KAAK,WAAW;AACf,MAAK,MAAM,SAAS,OAAO,OACzB,KAAI,MAAM,QAAqB,EAAE,QAAQ,MAAM,QAAQ;AAEzD,QAAO;GAET,EAAE,CACH"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { AnyEventDefinition } from "../events/plugin-event-types.mjs";
|
|
2
|
+
import { EventCapture } from "./services/event-capture.mjs";
|
|
3
|
+
import { PluginConfig } from "./services/plugin-config.mjs";
|
|
4
|
+
import { PluginLogger } from "./services/plugin-logger.mjs";
|
|
5
|
+
import { PluginRuntime } from "./services/plugin-runtime.mjs";
|
|
6
|
+
import { SessionInfo } from "./services/session-info.mjs";
|
|
7
|
+
import { Effect, Layer } from "effect";
|
|
8
|
+
import { PluginKey } from "@interfere/types/sdk/plugins/lib/types";
|
|
9
|
+
|
|
10
|
+
//#region src/core/plugins/define-plugin.d.ts
|
|
11
|
+
type BasePluginServices = EventCapture | SessionInfo | PluginConfig | PluginLogger | PluginRuntime;
|
|
12
|
+
interface PluginSetupResult<API = unknown> {
|
|
13
|
+
readonly api?: API;
|
|
14
|
+
readonly cleanup?: () => void;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* A loadable plugin definition. The private layer type `RPrivate` is hidden
|
|
18
|
+
* by capturing it in the `load` closure, avoiding variance issues when storing
|
|
19
|
+
* heterogeneous plugins in collections.
|
|
20
|
+
*/
|
|
21
|
+
interface PluginDef<K extends string = string, API = unknown> {
|
|
22
|
+
readonly events?: readonly AnyEventDefinition[];
|
|
23
|
+
readonly key: K;
|
|
24
|
+
readonly load: <R>(baseLayer: Layer.Layer<BasePluginServices, never, R>) => Effect.Effect<PluginSetupResult<API>, never, R>;
|
|
25
|
+
readonly name: string;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Define a plugin with a private layer. The `RPrivate` type parameter is
|
|
29
|
+
* captured in the returned `load` function closure, so callers don't need
|
|
30
|
+
* to know about it.
|
|
31
|
+
*
|
|
32
|
+
* The setup Effect receives both the plugin's private services (RPrivate) and
|
|
33
|
+
* the base plugin services (PluginRuntime, PluginLogger, etc.) so it can fork
|
|
34
|
+
* Effects via PluginRuntime.
|
|
35
|
+
*/
|
|
36
|
+
declare function definePlugin<K extends PluginKey, API, RPrivate>(key: K, options: {
|
|
37
|
+
readonly name: string;
|
|
38
|
+
readonly events?: readonly AnyEventDefinition[];
|
|
39
|
+
readonly layer: Layer.Layer<RPrivate, never, BasePluginServices>;
|
|
40
|
+
readonly setup: Effect.Effect<PluginSetupResult<API>, never, RPrivate | BasePluginServices>;
|
|
41
|
+
}): PluginDef<K, API>;
|
|
42
|
+
//#endregion
|
|
43
|
+
export { BasePluginServices, PluginDef, PluginSetupResult, definePlugin };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"define-plugin.d.mts","names":[],"sources":["../../../src/core/plugins/define-plugin.ts"],"mappings":";;;;;;;;;;KAWY,kBAAA,GACR,YAAA,GACA,WAAA,GACA,YAAA,GACA,YAAA,GACA,aAAA;AAAA,UAEa,iBAAA;EAAA,SACN,GAAA,GAAM,GAAA;EAAA,SACN,OAAA;AAAA;;;;;;UAQM,SAAA;EAAA,SACN,MAAA,YAAkB,kBAAA;EAAA,SAClB,GAAA,EAAK,CAAA;EAAA,SACL,IAAA,MACP,SAAA,EAAW,KAAA,CAAM,KAAA,CAAM,kBAAA,SAA2B,CAAA,MAC/C,MAAA,CAAO,MAAA,CAAO,iBAAA,CAAkB,GAAA,UAAa,CAAA;EAAA,SACzC,IAAA;AAAA;;;;AAhBX;;;;;;iBA4BgB,YAAA,WAAuB,SAAA,gBAAA,CACrC,GAAA,EAAK,CAAA,EACL,OAAA;EAAA,SACW,IAAA;EAAA,SACA,MAAA,YAAkB,kBAAA;EAAA,SAClB,KAAA,EAAO,KAAA,CAAM,KAAA,CAAM,QAAA,SAAiB,kBAAA;EAAA,SACpC,KAAA,EAAO,MAAA,CAAO,MAAA,CACrB,iBAAA,CAAkB,GAAA,UAElB,QAAA,GAAW,kBAAA;AAAA,IAGd,SAAA,CAAU,CAAA,EAAG,GAAA"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { Effect, Layer } from "effect";
|
|
2
|
+
|
|
3
|
+
//#region src/core/plugins/define-plugin.ts
|
|
4
|
+
/**
|
|
5
|
+
* Define a plugin with a private layer. The `RPrivate` type parameter is
|
|
6
|
+
* captured in the returned `load` function closure, so callers don't need
|
|
7
|
+
* to know about it.
|
|
8
|
+
*
|
|
9
|
+
* The setup Effect receives both the plugin's private services (RPrivate) and
|
|
10
|
+
* the base plugin services (PluginRuntime, PluginLogger, etc.) so it can fork
|
|
11
|
+
* Effects via PluginRuntime.
|
|
12
|
+
*/
|
|
13
|
+
function definePlugin(key, options) {
|
|
14
|
+
return {
|
|
15
|
+
key,
|
|
16
|
+
name: options.name,
|
|
17
|
+
events: options.events,
|
|
18
|
+
load: (baseLayer) => options.setup.pipe(Effect.provide(Layer.merge(options.layer.pipe(Layer.provide(baseLayer)), baseLayer)))
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
//#endregion
|
|
23
|
+
export { definePlugin };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"define-plugin.mjs","names":[],"sources":["../../../src/core/plugins/define-plugin.ts"],"sourcesContent":["import type { PluginKey } from \"@interfere/types/sdk/plugins/lib/types\";\n\nimport { Effect, Layer } from \"effect\";\n\nimport type { AnyEventDefinition } from \"../events/plugin-event-types.js\";\nimport type { EventCapture } from \"./services/event-capture.js\";\nimport type { PluginConfig } from \"./services/plugin-config.js\";\nimport type { PluginLogger } from \"./services/plugin-logger.js\";\nimport type { PluginRuntime } from \"./services/plugin-runtime.js\";\nimport type { SessionInfo } from \"./services/session-info.js\";\n\nexport type BasePluginServices =\n | EventCapture\n | SessionInfo\n | PluginConfig\n | PluginLogger\n | PluginRuntime;\n\nexport interface PluginSetupResult<API = unknown> {\n readonly api?: API;\n readonly cleanup?: () => void;\n}\n\n/**\n * A loadable plugin definition. The private layer type `RPrivate` is hidden\n * by capturing it in the `load` closure, avoiding variance issues when storing\n * heterogeneous plugins in collections.\n */\nexport interface PluginDef<K extends string = string, API = unknown> {\n readonly events?: readonly AnyEventDefinition[];\n readonly key: K;\n readonly load: <R>(\n baseLayer: Layer.Layer<BasePluginServices, never, R>\n ) => Effect.Effect<PluginSetupResult<API>, never, R>;\n readonly name: string;\n}\n\n/**\n * Define a plugin with a private layer. The `RPrivate` type parameter is\n * captured in the returned `load` function closure, so callers don't need\n * to know about it.\n *\n * The setup Effect receives both the plugin's private services (RPrivate) and\n * the base plugin services (PluginRuntime, PluginLogger, etc.) so it can fork\n * Effects via PluginRuntime.\n */\nexport function definePlugin<K extends PluginKey, API, RPrivate>(\n key: K,\n options: {\n readonly name: string;\n readonly events?: readonly AnyEventDefinition[];\n readonly layer: Layer.Layer<RPrivate, never, BasePluginServices>;\n readonly setup: Effect.Effect<\n PluginSetupResult<API>,\n never,\n RPrivate | BasePluginServices\n >;\n }\n): PluginDef<K, API> {\n return {\n key,\n name: options.name,\n events: options.events,\n load: (baseLayer) =>\n options.setup.pipe(\n Effect.provide(\n Layer.merge(options.layer.pipe(Layer.provide(baseLayer)), baseLayer)\n )\n ),\n };\n}\n"],"mappings":";;;;;;;;;;;;AA8CA,SAAgB,aACd,KACA,SAUmB;AACnB,QAAO;EACL;EACA,MAAM,QAAQ;EACd,QAAQ,QAAQ;EAChB,OAAO,cACL,QAAQ,MAAM,KACZ,OAAO,QACL,MAAM,MAAM,QAAQ,MAAM,KAAK,MAAM,QAAQ,UAAU,CAAC,EAAE,UAAU,CACrE,CACF;EACJ"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dom-utils.d.mts","names":[],"sources":["../../../src/core/plugins/dom-utils.ts"],"
|
|
1
|
+
{"version":3,"file":"dom-utils.d.mts","names":[],"sources":["../../../src/core/plugins/dom-utils.ts"],"mappings":";iBAIgB,kBAAA,CAAmB,OAAA,EAAS,OAAA;AAAA,iBAgB5B,cAAA,CAAe,OAAA,EAAS,WAAA;AAAA,cAU3B,QAAA;6BAGZ,kBAAA;yBAAA,cAAA;AAAA"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { EventPayload } from "../../../events/event-registry.mjs";
|
|
2
|
+
import { EventCapture } from "../../services/event-capture.mjs";
|
|
3
|
+
import { PluginLogger } from "../../services/plugin-logger.mjs";
|
|
4
|
+
import { Context, Effect, Layer } from "effect";
|
|
5
|
+
|
|
6
|
+
//#region src/core/plugins/impl/ai-summary/ai-summary-plugin-api.d.ts
|
|
7
|
+
type SessionSummaryPayload = EventPayload<"session_summary">;
|
|
8
|
+
interface AiSummaryPluginApiService {
|
|
9
|
+
readonly captureSessionSummary: (payload: SessionSummaryPayload) => Effect.Effect<void>;
|
|
10
|
+
readonly log: {
|
|
11
|
+
readonly debug: (message: string) => Effect.Effect<void>;
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
declare const AiSummaryPluginApi_base: Context.TagClass<AiSummaryPluginApi, "@interfere/plugins/ai-summary/AiSummaryPluginApi", AiSummaryPluginApiService>;
|
|
15
|
+
declare class AiSummaryPluginApi extends AiSummaryPluginApi_base {}
|
|
16
|
+
declare const AiSummaryPluginApiLayer: Layer.Layer<AiSummaryPluginApi, never, EventCapture | PluginLogger>;
|
|
17
|
+
//#endregion
|
|
18
|
+
export { AiSummaryPluginApi, AiSummaryPluginApiLayer };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ai-summary-plugin-api.d.mts","names":[],"sources":["../../../../../src/core/plugins/impl/ai-summary/ai-summary-plugin-api.ts"],"mappings":";;;;;;KAMK,qBAAA,GAAwB,YAAA;AAAA,UAEnB,yBAAA;EAAA,SACC,qBAAA,GACP,OAAA,EAAS,qBAAA,KACN,MAAA,CAAO,MAAA;EAAA,SACH,GAAA;IAAA,SACE,KAAA,GAAQ,OAAA,aAAoB,MAAA,CAAO,MAAA;EAAA;AAAA;AAAA,cAAM,uBAAA;cAIzC,kBAAA,SAA2B,uBAAA;AAAA,cAI3B,uBAAA,EAAuB,KAAA,CAAA,KAAA,CAAA,kBAAA,SAAA,YAAA,GAAA,YAAA"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { EventCapture } from "../../services/event-capture.mjs";
|
|
2
|
+
import { PluginLogger } from "../../services/plugin-logger.mjs";
|
|
3
|
+
import { Context, Effect, Layer } from "effect";
|
|
4
|
+
|
|
5
|
+
//#region src/core/plugins/impl/ai-summary/ai-summary-plugin-api.ts
|
|
6
|
+
var AiSummaryPluginApi = class extends Context.Tag("@interfere/plugins/ai-summary/AiSummaryPluginApi")() {};
|
|
7
|
+
const AiSummaryPluginApiLayer = Layer.effect(AiSummaryPluginApi, Effect.gen(function* () {
|
|
8
|
+
const capture = yield* EventCapture;
|
|
9
|
+
const logger = yield* PluginLogger;
|
|
10
|
+
return AiSummaryPluginApi.of({
|
|
11
|
+
captureSessionSummary: (payload) => capture.capture("session_summary", payload).pipe(Effect.withSpan("plugin.ai.session_summary")),
|
|
12
|
+
log: { debug: logger.debug }
|
|
13
|
+
});
|
|
14
|
+
}));
|
|
15
|
+
|
|
16
|
+
//#endregion
|
|
17
|
+
export { AiSummaryPluginApi, AiSummaryPluginApiLayer };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ai-summary-plugin-api.mjs","names":[],"sources":["../../../../../src/core/plugins/impl/ai-summary/ai-summary-plugin-api.ts"],"sourcesContent":["import { Context, Effect, Layer } from \"effect\";\n\nimport type { EventPayload } from \"../../../events/event-registry.js\";\nimport { EventCapture } from \"../../services/event-capture.js\";\nimport { PluginLogger } from \"../../services/plugin-logger.js\";\n\ntype SessionSummaryPayload = EventPayload<\"session_summary\">;\n\ninterface AiSummaryPluginApiService {\n readonly captureSessionSummary: (\n payload: SessionSummaryPayload\n ) => Effect.Effect<void>;\n readonly log: {\n readonly debug: (message: string) => Effect.Effect<void>;\n };\n}\n\nexport class AiSummaryPluginApi extends Context.Tag(\n \"@interfere/plugins/ai-summary/AiSummaryPluginApi\"\n)<AiSummaryPluginApi, AiSummaryPluginApiService>() {}\n\nexport const AiSummaryPluginApiLayer = Layer.effect(\n AiSummaryPluginApi,\n Effect.gen(function* () {\n const capture = yield* EventCapture;\n const logger = yield* PluginLogger;\n\n return AiSummaryPluginApi.of({\n captureSessionSummary: (payload) =>\n capture\n .capture(\"session_summary\", payload)\n .pipe(Effect.withSpan(\"plugin.ai.session_summary\")),\n log: {\n debug: logger.debug,\n },\n });\n })\n);\n"],"mappings":";;;;;AAiBA,IAAa,qBAAb,cAAwC,QAAQ,IAC9C,mDACD,EAAiD,CAAC;AAEnD,MAAa,0BAA0B,MAAM,OAC3C,oBACA,OAAO,IAAI,aAAa;CACtB,MAAM,UAAU,OAAO;CACvB,MAAM,SAAS,OAAO;AAEtB,QAAO,mBAAmB,GAAG;EAC3B,wBAAwB,YACtB,QACG,QAAQ,mBAAmB,QAAQ,CACnC,KAAK,OAAO,SAAS,4BAA4B,CAAC;EACvD,KAAK,EACH,OAAO,OAAO,OACf;EACF,CAAC;EACF,CACH"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plugin.d.mts","names":[],"sources":["../../../../../src/core/plugins/impl/ai-summary/plugin.ts"],"mappings":""}
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
import { PluginRuntime } from "../../services/plugin-runtime.mjs";
|
|
2
|
+
import { definePlugin } from "../../define-plugin.mjs";
|
|
3
|
+
import { defineEvent } from "../../../events/define-event.mjs";
|
|
4
|
+
import { AiSummaryPluginApi, AiSummaryPluginApiLayer } from "./ai-summary-plugin-api.mjs";
|
|
5
|
+
import { Data, Duration, Effect, Fiber, Ref } from "effect";
|
|
6
|
+
|
|
7
|
+
//#region src/core/plugins/impl/ai-summary/plugin.ts
|
|
8
|
+
const MIN_CAPTURE_INTERVAL_MS = 3e4;
|
|
9
|
+
const INITIAL_CAPTURE_DELAY_MS = 5e3;
|
|
10
|
+
const DEBOUNCE_DELAY_MS = 2e3;
|
|
11
|
+
const MIN_TEXT_LENGTH = 100;
|
|
12
|
+
const MAX_TEXT_LENGTH = 5e4;
|
|
13
|
+
const MAX_CONTEXT_TEXT_LENGTH = 1e4;
|
|
14
|
+
const MIN_NODE_TEXT_LENGTH = 3;
|
|
15
|
+
const MIN_SUMMARY_LENGTH = 20;
|
|
16
|
+
var AiSummaryCreateFailed = class extends Data.TaggedError("AiSummaryCreateFailed") {};
|
|
17
|
+
var AiSummaryPromptFailed = class extends Data.TaggedError("AiSummaryPromptFailed") {};
|
|
18
|
+
var plugin_default = definePlugin("aiSummary", {
|
|
19
|
+
name: "aiSummary",
|
|
20
|
+
events: [defineEvent("session_summary").value()],
|
|
21
|
+
layer: AiSummaryPluginApiLayer,
|
|
22
|
+
setup: Effect.gen(function* () {
|
|
23
|
+
const api = yield* AiSummaryPluginApi;
|
|
24
|
+
const runtime = yield* PluginRuntime;
|
|
25
|
+
if (typeof window === "undefined" || typeof document === "undefined" || !("ai" in window) || !window.ai?.summarizer) {
|
|
26
|
+
yield* api.log.debug("aiSummary: unsupported environment or missing API");
|
|
27
|
+
return {};
|
|
28
|
+
}
|
|
29
|
+
const ai = window.ai;
|
|
30
|
+
if ((yield* Effect.promise(() => ai.summarizer?.capabilities() ?? Promise.resolve({ available: "no" })))?.available !== "readily") {
|
|
31
|
+
yield* api.log.debug("aiSummary: summarizer not readily available");
|
|
32
|
+
return {};
|
|
33
|
+
}
|
|
34
|
+
if (!ai.summarizer) {
|
|
35
|
+
yield* api.log.debug("aiSummary: summarizer missing after capability check");
|
|
36
|
+
return {};
|
|
37
|
+
}
|
|
38
|
+
const isCapturingRef = yield* Ref.make(false);
|
|
39
|
+
const lastCaptureTimeRef = yield* Ref.make(0);
|
|
40
|
+
const scheduledFiberRef = yield* Ref.make(null);
|
|
41
|
+
const shouldSkipForLength = (text) => text.length < MIN_TEXT_LENGTH || text.length > MAX_TEXT_LENGTH;
|
|
42
|
+
const acceptTextNode = (textNode) => {
|
|
43
|
+
const parent = textNode.parentElement;
|
|
44
|
+
if (!parent) return NodeFilter.FILTER_REJECT;
|
|
45
|
+
const tagName = parent.tagName.toLowerCase();
|
|
46
|
+
if (tagName === "script" || tagName === "style" || tagName === "noscript") return NodeFilter.FILTER_REJECT;
|
|
47
|
+
const style = window.getComputedStyle(parent);
|
|
48
|
+
if (style.display === "none" || style.visibility === "hidden" || style.opacity === "0") return NodeFilter.FILTER_REJECT;
|
|
49
|
+
const text = textNode.textContent?.trim();
|
|
50
|
+
if (!text || text.length < MIN_NODE_TEXT_LENGTH) return NodeFilter.FILTER_REJECT;
|
|
51
|
+
return NodeFilter.FILTER_ACCEPT;
|
|
52
|
+
};
|
|
53
|
+
const extractVisibleText = () => {
|
|
54
|
+
const walker = document.createTreeWalker(document.body, NodeFilter.SHOW_TEXT, { acceptNode: acceptTextNode });
|
|
55
|
+
const parts = [];
|
|
56
|
+
let current = walker.nextNode();
|
|
57
|
+
while (current) {
|
|
58
|
+
const text = current.textContent?.trim();
|
|
59
|
+
if (text && text.length >= MIN_NODE_TEXT_LENGTH) parts.push(text);
|
|
60
|
+
current = walker.nextNode();
|
|
61
|
+
}
|
|
62
|
+
return parts.join(" ");
|
|
63
|
+
};
|
|
64
|
+
const buildContextText = (title, url, description, content) => {
|
|
65
|
+
return `Title: ${title}\nURL: ${url}\n${description ? `Description: ${description}\n` : ""}Content: ${content.substring(0, MAX_CONTEXT_TEXT_LENGTH)}`;
|
|
66
|
+
};
|
|
67
|
+
const getPageMetadata = () => {
|
|
68
|
+
return {
|
|
69
|
+
title: document.title || "Untitled",
|
|
70
|
+
url: window.location.href,
|
|
71
|
+
description: document.querySelector("meta[name=\"description\"]")?.getAttribute("content") || ""
|
|
72
|
+
};
|
|
73
|
+
};
|
|
74
|
+
const isSummaryMeaningful = (text) => Boolean(text && text.length > MIN_SUMMARY_LENGTH);
|
|
75
|
+
const performSummaryFlow = Effect.fn("AiSummary.performSummaryFlow")((nowTs) => Effect.gen(function* () {
|
|
76
|
+
const fullText = extractVisibleText();
|
|
77
|
+
if (shouldSkipForLength(fullText)) return;
|
|
78
|
+
const { title, url, description } = getPageMetadata();
|
|
79
|
+
const contextualText = buildContextText(title, url, description, fullText);
|
|
80
|
+
const summarizer = ai.summarizer;
|
|
81
|
+
if (!summarizer) return;
|
|
82
|
+
const session = yield* Effect.tryPromise({
|
|
83
|
+
try: () => summarizer.create(),
|
|
84
|
+
catch: (cause) => new AiSummaryCreateFailed({
|
|
85
|
+
message: "AI summarizer create() failed",
|
|
86
|
+
cause
|
|
87
|
+
})
|
|
88
|
+
}).pipe(Effect.catchAll((error) => api.log.debug(`AI summarizer create() failed: ${error.message}`).pipe(Effect.as(null))));
|
|
89
|
+
if (!session) return;
|
|
90
|
+
const summary = yield* Effect.tryPromise({
|
|
91
|
+
try: () => session.prompt(contextualText),
|
|
92
|
+
catch: (cause) => new AiSummaryPromptFailed({
|
|
93
|
+
message: "AI summarizer prompt() failed",
|
|
94
|
+
cause
|
|
95
|
+
})
|
|
96
|
+
}).pipe(Effect.catchAll((error) => api.log.debug(`AI summarizer prompt() failed: ${error.message}`).pipe(Effect.as(null))));
|
|
97
|
+
if (!(typeof summary === "string" && isSummaryMeaningful(summary))) return;
|
|
98
|
+
yield* api.captureSessionSummary({
|
|
99
|
+
summary,
|
|
100
|
+
pageTitle: title,
|
|
101
|
+
pageUrl: url,
|
|
102
|
+
contentLength: fullText.length,
|
|
103
|
+
timestamp: nowTs
|
|
104
|
+
});
|
|
105
|
+
}));
|
|
106
|
+
const captureNow = Effect.fn("AiSummary.captureNow")(function* () {
|
|
107
|
+
const nowTs = Date.now();
|
|
108
|
+
const isCapturing = yield* Ref.get(isCapturingRef);
|
|
109
|
+
const lastCaptureTime = yield* Ref.get(lastCaptureTimeRef);
|
|
110
|
+
if (isCapturing || nowTs - lastCaptureTime < MIN_CAPTURE_INTERVAL_MS) return;
|
|
111
|
+
yield* Ref.set(isCapturingRef, true);
|
|
112
|
+
yield* Ref.set(lastCaptureTimeRef, nowTs);
|
|
113
|
+
yield* performSummaryFlow(nowTs).pipe(Effect.ensuring(Ref.set(isCapturingRef, false)));
|
|
114
|
+
});
|
|
115
|
+
const scheduleCapture = Effect.fn("AiSummary.scheduleCapture")((delayMs) => Effect.gen(function* () {
|
|
116
|
+
if (yield* Ref.get(isCapturingRef)) return;
|
|
117
|
+
const previousFiber = yield* Ref.get(scheduledFiberRef);
|
|
118
|
+
if (previousFiber) yield* Fiber.interrupt(previousFiber);
|
|
119
|
+
const fiber = yield* Effect.sleep(Duration.millis(delayMs)).pipe(Effect.zipRight(captureNow()), Effect.forkDaemon);
|
|
120
|
+
yield* Ref.set(scheduledFiberRef, fiber);
|
|
121
|
+
}));
|
|
122
|
+
const observer = new MutationObserver(() => {
|
|
123
|
+
runtime.fork(scheduleCapture(DEBOUNCE_DELAY_MS));
|
|
124
|
+
});
|
|
125
|
+
observer.observe(document.body, {
|
|
126
|
+
childList: true,
|
|
127
|
+
subtree: true,
|
|
128
|
+
characterData: false,
|
|
129
|
+
attributes: false
|
|
130
|
+
});
|
|
131
|
+
const handleVisibilityChange = () => {
|
|
132
|
+
if (document.visibilityState === "visible") runtime.fork(captureNow());
|
|
133
|
+
};
|
|
134
|
+
document.addEventListener("visibilitychange", handleVisibilityChange);
|
|
135
|
+
yield* scheduleCapture(INITIAL_CAPTURE_DELAY_MS);
|
|
136
|
+
return { cleanup: () => {
|
|
137
|
+
observer.disconnect();
|
|
138
|
+
document.removeEventListener("visibilitychange", handleVisibilityChange);
|
|
139
|
+
runtime.fork(Effect.gen(function* () {
|
|
140
|
+
const fiber = yield* Ref.get(scheduledFiberRef);
|
|
141
|
+
if (fiber) {
|
|
142
|
+
yield* Fiber.interrupt(fiber);
|
|
143
|
+
yield* Ref.set(scheduledFiberRef, null);
|
|
144
|
+
}
|
|
145
|
+
}));
|
|
146
|
+
} };
|
|
147
|
+
}).pipe(Effect.withSpan("plugins.aiSummary.setup"))
|
|
148
|
+
});
|
|
149
|
+
|
|
150
|
+
//#endregion
|
|
151
|
+
export { plugin_default as default };
|