@mochabug/adapt-astro 1.0.0-rc12 → 1.0.0-rc15

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mochabug/adapt-astro",
3
- "version": "1.0.0-rc12",
3
+ "version": "1.0.0-rc15",
4
4
  "description": "Astro component for Adapt automation platform",
5
5
  "type": "module",
6
6
  "main": "./src/index.ts",
@@ -31,6 +31,6 @@
31
31
  "astro": "^3.0.0 || ^4.0.0 || ^5.0.0"
32
32
  },
33
33
  "dependencies": {
34
- "@mochabug/adapt-web": "^1.0.0-rc34"
34
+ "@mochabug/adapt-web": "^1.0.0-rc37"
35
35
  }
36
36
  }
package/src/Adapt.astro CHANGED
@@ -9,6 +9,9 @@ export interface Props
9
9
  | "authToken"
10
10
  | "transmitter"
11
11
  | "signals"
12
+ | "challengeToken"
13
+ | "requiresChallenge"
14
+ | "capWidgetOptions"
12
15
  | "inheritToken"
13
16
  | "inheritFrom"
14
17
  | "forkDisplayMode"
@@ -32,6 +35,9 @@ const {
32
35
  authToken,
33
36
  transmitter,
34
37
  signals,
38
+ challengeToken,
39
+ requiresChallenge = false,
40
+ capWidgetOptions,
35
41
  inheritToken,
36
42
  inheritFrom,
37
43
  forkDisplayMode = "side-by-side",
@@ -58,6 +64,9 @@ const containerId = `adapt-${Math.random().toString(36).slice(2, 11)}`;
58
64
  data-adapt-auth-token={authToken}
59
65
  data-adapt-transmitter={transmitter}
60
66
  data-adapt-signals={signals ? JSON.stringify(signals) : undefined}
67
+ data-adapt-challenge-token={challengeToken}
68
+ data-adapt-requires-challenge={requiresChallenge}
69
+ data-adapt-cap-widget-options={capWidgetOptions ? JSON.stringify(capWidgetOptions) : undefined}
61
70
  data-adapt-inherit-token={inheritToken}
62
71
  data-adapt-inherit-from={inheritFrom ? JSON.stringify(inheritFrom) : undefined}
63
72
  data-adapt-fork-display-mode={forkDisplayMode}
@@ -78,6 +87,7 @@ const containerId = `adapt-${Math.random().toString(36).slice(2, 11)}`;
78
87
  const inheritFromStr = container.dataset.adaptInheritFrom;
79
88
  const classNamesStr = container.dataset.adaptClassNames;
80
89
  const signalsStr = container.dataset.adaptSignals;
90
+ const capWidgetOptionsStr = container.dataset.adaptCapWidgetOptions;
81
91
 
82
92
  const client = new AdaptWebClient({
83
93
  container: container.id,
@@ -86,6 +96,9 @@ const containerId = `adapt-${Math.random().toString(36).slice(2, 11)}`;
86
96
  authToken: container.dataset.adaptAuthToken,
87
97
  transmitter: container.dataset.adaptTransmitter,
88
98
  signals: signalsStr ? JSON.parse(signalsStr) : undefined,
99
+ challengeToken: container.dataset.adaptChallengeToken,
100
+ requiresChallenge: container.dataset.adaptRequiresChallenge === "true",
101
+ capWidgetOptions: capWidgetOptionsStr ? JSON.parse(capWidgetOptionsStr) : undefined,
89
102
  inheritToken: container.dataset.adaptInheritToken,
90
103
  inheritFrom: inheritFromStr ? JSON.parse(inheritFromStr) : undefined,
91
104
  forkDisplayMode: container.dataset.adaptForkDisplayMode as "side-by-side" | "dialog",
@@ -0,0 +1,161 @@
1
+ ---
2
+ import type { CapWidgetI18n } from "@mochabug/adapt-web";
3
+
4
+ export interface Props {
5
+ /** Automation ID for challenge endpoints */
6
+ automationId: string;
7
+ /** Number of workers for Cap.js */
8
+ workerCount?: number;
9
+ /** Custom labels for Cap.js widget */
10
+ i18n?: CapWidgetI18n;
11
+ /** Enable dark mode styling */
12
+ darkMode?: boolean;
13
+ /** CSS class name for the container */
14
+ class?: string;
15
+ /** Inline styles for the container */
16
+ style?: string;
17
+ }
18
+
19
+ const {
20
+ automationId,
21
+ workerCount,
22
+ i18n,
23
+ darkMode = false,
24
+ class: className,
25
+ style,
26
+ } = Astro.props;
27
+
28
+ const containerId = `adapt-cap-${Math.random().toString(36).slice(2, 11)}`;
29
+ ---
30
+
31
+ <!--
32
+ AdaptCap Astro component for proof-of-work challenges.
33
+
34
+ Since the client object is only available at runtime, you must initialize it
35
+ via JavaScript after creating the client:
36
+
37
+ ```js
38
+ import { createConnectClient } from "@mochabug/adapt-core/connect";
39
+
40
+ const rawClient = createConnectClient({ id: "my-automation" });
41
+
42
+ // Find the container and dispatch the init event with the client
43
+ const container = document.querySelector('[data-adapt-cap-automation-id="my-automation"]');
44
+ container.dispatchEvent(new CustomEvent('adapt-cap:init', {
45
+ detail: { client: rawClient }
46
+ }));
47
+
48
+ // Listen for solve event
49
+ container.addEventListener('adapt-cap:solve', (e) => {
50
+ const { token, expires } = e.detail;
51
+ // Use token with client.run({ challengeToken: token })
52
+ });
53
+ ```
54
+ -->
55
+ <div
56
+ id={containerId}
57
+ class={className}
58
+ style={style}
59
+ data-adapt-cap-automation-id={automationId}
60
+ data-adapt-cap-worker-count={workerCount}
61
+ data-adapt-cap-i18n={i18n ? JSON.stringify(i18n) : undefined}
62
+ data-adapt-cap-dark-mode={darkMode}
63
+ >
64
+ </div>
65
+
66
+ <script>
67
+ import {
68
+ AdaptCapWidget,
69
+ type AdaptCapWidgetOptions,
70
+ } from "@mochabug/adapt-web";
71
+ import type { AutomationClient } from "@mochabug/adapt-core";
72
+
73
+ function initAdaptCap(container: HTMLElement, client: AutomationClient) {
74
+ const automationId = container.dataset.adaptCapAutomationId;
75
+ if (!automationId) return;
76
+
77
+ // Cleanup existing widget if any
78
+ const existingWidget = (container as any).__adaptCapWidget;
79
+ if (existingWidget) {
80
+ existingWidget.destroy();
81
+ }
82
+
83
+ const i18nStr = container.dataset.adaptCapI18n;
84
+
85
+ const options: AdaptCapWidgetOptions = {
86
+ container,
87
+ automationId,
88
+ client,
89
+ onSolve: (token, expires) => {
90
+ container.dispatchEvent(
91
+ new CustomEvent("adapt-cap:solve", {
92
+ detail: { token, expires },
93
+ bubbles: true,
94
+ })
95
+ );
96
+ },
97
+ onError: (error) => {
98
+ container.dispatchEvent(
99
+ new CustomEvent("adapt-cap:error", {
100
+ detail: { error },
101
+ bubbles: true,
102
+ })
103
+ );
104
+ },
105
+ };
106
+
107
+ // Parse optional props
108
+ const workerCount = container.dataset.adaptCapWorkerCount;
109
+ if (workerCount) {
110
+ options.workerCount = Number(workerCount);
111
+ }
112
+ if (i18nStr) {
113
+ options.i18n = JSON.parse(i18nStr);
114
+ }
115
+
116
+ const widget = new AdaptCapWidget(options);
117
+
118
+ // Apply dark mode
119
+ if (container.dataset.adaptCapDarkMode === "true") {
120
+ widget.setDarkMode(true);
121
+ }
122
+
123
+ // Store reference for cleanup
124
+ (container as any).__adaptCapWidget = widget;
125
+ }
126
+
127
+ function cleanupAdaptCap(container: HTMLElement) {
128
+ const widget = (container as any).__adaptCapWidget;
129
+ if (widget) {
130
+ widget.destroy();
131
+ delete (container as any).__adaptCapWidget;
132
+ }
133
+ }
134
+
135
+ // Set up init event listeners for all containers
136
+ function setupInitListeners() {
137
+ document
138
+ .querySelectorAll<HTMLElement>("[data-adapt-cap-automation-id]")
139
+ .forEach((container) => {
140
+ // Listen for init event with client
141
+ container.addEventListener("adapt-cap:init", ((
142
+ e: CustomEvent<{ client: AutomationClient }>
143
+ ) => {
144
+ initAdaptCap(container, e.detail.client);
145
+ }) as EventListener);
146
+ });
147
+ }
148
+
149
+ // Initial setup
150
+ setupInitListeners();
151
+
152
+ // Handle Astro View Transitions (page navigation without full reload)
153
+ document.addEventListener("astro:page-load", setupInitListeners);
154
+
155
+ // Cleanup before page swap (View Transitions)
156
+ document.addEventListener("astro:before-swap", () => {
157
+ document
158
+ .querySelectorAll<HTMLElement>("[data-adapt-cap-automation-id]")
159
+ .forEach(cleanupAdaptCap);
160
+ });
161
+ </script>