@absolutejs/absolute 0.19.0-beta.1052 → 0.19.0-beta.1053
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/angular/browser.js +3 -2
- package/dist/angular/browser.js.map +6 -6
- package/dist/angular/components/constants.js +6 -0
- package/dist/angular/components/core/streamingSlotRegistrar.js +1 -1
- package/dist/angular/components/core/streamingSlotRegistry.js +2 -2
- package/dist/angular/hmrPreserveCore.ts +2 -8
- package/dist/angular/index.js +3 -2
- package/dist/angular/index.js.map +8 -8
- package/dist/angular/server.js +3 -2
- package/dist/angular/server.js.map +5 -5
- package/dist/build.js +49 -15
- package/dist/build.js.map +24 -24
- package/dist/cli/config/client.js +1 -1
- package/dist/cli/config/server.js +93 -28
- package/dist/cli/index.js +101 -25
- package/dist/client/index.js.map +1 -1
- package/dist/dev/client/errorOverlay.ts +4 -4
- package/dist/dev/client/handlers/angularHmrShim.ts +1 -1
- package/dist/dev/client/handlers/angularRemount.ts +1 -4
- package/dist/dev/client/handlers/angularRemountWiring.ts +0 -1
- package/dist/index.js +50 -15
- package/dist/index.js.map +26 -26
- package/dist/islands/browser.js.map +1 -1
- package/dist/islands/index.js +3 -2
- package/dist/islands/index.js.map +4 -4
- package/dist/react/browser.js.map +1 -1
- package/dist/react/components/index.js +3 -2
- package/dist/react/components/index.js.map +3 -3
- package/dist/react/hooks/index.js.map +1 -1
- package/dist/react/index.js +3 -2
- package/dist/react/index.js.map +6 -6
- package/dist/react/server.js +3 -2
- package/dist/react/server.js.map +5 -5
- package/dist/src/angular/components/constants.d.ts +1 -0
- package/dist/src/constants.d.ts +1 -0
- package/dist/svelte/browser.js.map +1 -1
- package/dist/svelte/index.js +3 -2
- package/dist/svelte/index.js.map +6 -6
- package/dist/svelte/router/hashMode.ts +1 -1
- package/dist/svelte/router/prefetchCache.ts +3 -3
- package/dist/svelte/server.js +3 -2
- package/dist/svelte/server.js.map +5 -5
- package/dist/types/globals.d.ts +1 -3
- package/dist/vue/browser.js.map +1 -1
- package/dist/vue/components/Image.js +3 -2
- package/dist/vue/components/Image.js.map +3 -3
- package/dist/vue/components/index.js +3 -2
- package/dist/vue/components/index.js.map +3 -3
- package/dist/vue/index.js +3 -2
- package/dist/vue/index.js.map +7 -7
- package/dist/vue/server.js +3 -2
- package/dist/vue/server.js.map +6 -6
- package/package.json +1 -1
|
@@ -31540,7 +31540,9 @@ var VIRTUAL_NAME = "__absolute_type_introspect__.ts", MAX_DEPTH2 = 6, isFramewor
|
|
|
31540
31540
|
const candidates = specifier === "@absolutejs/absolute" ? [
|
|
31541
31541
|
resolve6(cwd, "node_modules", "@absolutejs", "absolute", "package.json"),
|
|
31542
31542
|
resolve6(cwd, "package.json")
|
|
31543
|
-
] : [
|
|
31543
|
+
] : [
|
|
31544
|
+
resolve6(cwd, "node_modules", ...specifier.split("/"), "package.json")
|
|
31545
|
+
];
|
|
31544
31546
|
for (const candidate of candidates) {
|
|
31545
31547
|
try {
|
|
31546
31548
|
const { version: version3 } = JSON.parse(readFileSync9(candidate, "utf-8"));
|
|
@@ -32111,7 +32113,10 @@ var init_authScaffolds = __esm(() => {
|
|
|
32111
32113
|
configKey: "compliance",
|
|
32112
32114
|
exportName: "complianceConfig",
|
|
32113
32115
|
fields: [
|
|
32114
|
-
{
|
|
32116
|
+
{
|
|
32117
|
+
name: "deleteUserData",
|
|
32118
|
+
value: TODO("erase or anonymize the user in your stores")
|
|
32119
|
+
},
|
|
32115
32120
|
{ name: "exportUserData", value: "async ({ user }) => ({})" },
|
|
32116
32121
|
{ name: "getUserId", value: "(user) => user.sub" }
|
|
32117
32122
|
],
|
|
@@ -32125,10 +32130,19 @@ var init_authScaffolds = __esm(() => {
|
|
|
32125
32130
|
configKey: "credentials",
|
|
32126
32131
|
exportName: "credentialsConfig",
|
|
32127
32132
|
fields: [
|
|
32128
|
-
{
|
|
32133
|
+
{
|
|
32134
|
+
name: "credentialStore",
|
|
32135
|
+
value: "createInMemoryCredentialStore()"
|
|
32136
|
+
},
|
|
32129
32137
|
{ name: "getUserByEmail", value: TODO("look up a user by email") },
|
|
32130
|
-
{
|
|
32131
|
-
|
|
32138
|
+
{
|
|
32139
|
+
name: "onCreateCredentialUser",
|
|
32140
|
+
value: TODO("create and return the user for identity.email")
|
|
32141
|
+
},
|
|
32142
|
+
{
|
|
32143
|
+
name: "onSendEmail",
|
|
32144
|
+
value: TODO("send the verification / reset email containing message.token")
|
|
32145
|
+
},
|
|
32132
32146
|
{ name: "requireEmailVerification", value: "false" }
|
|
32133
32147
|
],
|
|
32134
32148
|
generic: true,
|
|
@@ -32157,7 +32171,10 @@ var init_authScaffolds = __esm(() => {
|
|
|
32157
32171
|
fields: [
|
|
32158
32172
|
{ name: "mfaStore", value: "createInMemoryMfaStore()" },
|
|
32159
32173
|
{ name: "getUserId", value: "(user) => user.sub" },
|
|
32160
|
-
{
|
|
32174
|
+
{
|
|
32175
|
+
name: "getChallengeUser",
|
|
32176
|
+
value: TODO("resolve the parked challenge identity to a user")
|
|
32177
|
+
},
|
|
32161
32178
|
{ name: "issuer", value: "'YourApp'" }
|
|
32162
32179
|
],
|
|
32163
32180
|
generic: true,
|
|
@@ -32171,7 +32188,10 @@ var init_authScaffolds = __esm(() => {
|
|
|
32171
32188
|
exportName: "organizationsConfig",
|
|
32172
32189
|
fields: [
|
|
32173
32190
|
{ name: "getUserId", value: "(user) => user.sub" },
|
|
32174
|
-
{
|
|
32191
|
+
{
|
|
32192
|
+
name: "organizationStore",
|
|
32193
|
+
value: "createInMemoryOrganizationStore()"
|
|
32194
|
+
}
|
|
32175
32195
|
],
|
|
32176
32196
|
generic: true,
|
|
32177
32197
|
imports: ["createInMemoryOrganizationStore"],
|
|
@@ -32183,9 +32203,15 @@ var init_authScaffolds = __esm(() => {
|
|
|
32183
32203
|
configKey: "passwordless",
|
|
32184
32204
|
exportName: "passwordlessConfig",
|
|
32185
32205
|
fields: [
|
|
32186
|
-
{
|
|
32206
|
+
{
|
|
32207
|
+
name: "passwordlessTokenStore",
|
|
32208
|
+
value: "createInMemoryPasswordlessTokenStore()"
|
|
32209
|
+
},
|
|
32187
32210
|
{ name: "getUserByEmail", value: TODO("look up a user by email") },
|
|
32188
|
-
{
|
|
32211
|
+
{
|
|
32212
|
+
name: "onSendMagicLink",
|
|
32213
|
+
value: TODO("email the magic link containing message.token")
|
|
32214
|
+
}
|
|
32189
32215
|
],
|
|
32190
32216
|
generic: true,
|
|
32191
32217
|
imports: ["createInMemoryPasswordlessTokenStore"],
|
|
@@ -32197,7 +32223,10 @@ var init_authScaffolds = __esm(() => {
|
|
|
32197
32223
|
configKey: "portal",
|
|
32198
32224
|
exportName: "portalConfig",
|
|
32199
32225
|
fields: [
|
|
32200
|
-
{
|
|
32226
|
+
{
|
|
32227
|
+
name: "setupSessionStore",
|
|
32228
|
+
value: "createInMemorySetupSessionStore()"
|
|
32229
|
+
}
|
|
32201
32230
|
],
|
|
32202
32231
|
generic: false,
|
|
32203
32232
|
imports: ["createInMemorySetupSessionStore"],
|
|
@@ -32210,7 +32239,10 @@ var init_authScaffolds = __esm(() => {
|
|
|
32210
32239
|
exportName: "rolesConfig",
|
|
32211
32240
|
fields: [
|
|
32212
32241
|
{ name: "getUserId", value: "(user) => user.sub" },
|
|
32213
|
-
{
|
|
32242
|
+
{
|
|
32243
|
+
name: "organizationStore",
|
|
32244
|
+
value: "createInMemoryOrganizationStore()"
|
|
32245
|
+
},
|
|
32214
32246
|
{ name: "roleStore", value: "createInMemoryRoleStore()" }
|
|
32215
32247
|
],
|
|
32216
32248
|
generic: true,
|
|
@@ -32224,11 +32256,23 @@ var init_authScaffolds = __esm(() => {
|
|
|
32224
32256
|
exportName: "scimConfig",
|
|
32225
32257
|
fields: [
|
|
32226
32258
|
{ name: "scimTokenStore", value: "createInMemoryScimTokenStore()" },
|
|
32227
|
-
{
|
|
32259
|
+
{
|
|
32260
|
+
name: "getScimUser",
|
|
32261
|
+
value: TODO("return the SCIM user for { id, organizationId }")
|
|
32262
|
+
},
|
|
32228
32263
|
{ name: "listScimUsers", value: "async () => []" },
|
|
32229
|
-
{
|
|
32230
|
-
|
|
32231
|
-
|
|
32264
|
+
{
|
|
32265
|
+
name: "onScimUserCreate",
|
|
32266
|
+
value: TODO("create and return the SCIM user")
|
|
32267
|
+
},
|
|
32268
|
+
{
|
|
32269
|
+
name: "onScimUserDeactivate",
|
|
32270
|
+
value: TODO("deprovision the user (hard-delete or deactivate)")
|
|
32271
|
+
},
|
|
32272
|
+
{
|
|
32273
|
+
name: "onScimUserReplace",
|
|
32274
|
+
value: TODO("replace and return the SCIM user (undefined if unknown)")
|
|
32275
|
+
}
|
|
32232
32276
|
],
|
|
32233
32277
|
generic: false,
|
|
32234
32278
|
imports: ["createInMemoryScimTokenStore"],
|
|
@@ -32250,8 +32294,14 @@ var init_authScaffolds = __esm(() => {
|
|
|
32250
32294
|
configKey: "sso",
|
|
32251
32295
|
exportName: "ssoConfig",
|
|
32252
32296
|
fields: [
|
|
32253
|
-
{
|
|
32254
|
-
|
|
32297
|
+
{
|
|
32298
|
+
name: "ssoConnectionStore",
|
|
32299
|
+
value: "createInMemorySsoConnectionStore()"
|
|
32300
|
+
},
|
|
32301
|
+
{
|
|
32302
|
+
name: "getSsoUser",
|
|
32303
|
+
value: TODO("map the verified SSO identity to your user (create on first sign-in)")
|
|
32304
|
+
}
|
|
32255
32305
|
],
|
|
32256
32306
|
generic: true,
|
|
32257
32307
|
imports: ["createInMemorySsoConnectionStore"],
|
|
@@ -32263,9 +32313,15 @@ var init_authScaffolds = __esm(() => {
|
|
|
32263
32313
|
configKey: "webauthn",
|
|
32264
32314
|
exportName: "webauthnConfig",
|
|
32265
32315
|
fields: [
|
|
32266
|
-
{
|
|
32316
|
+
{
|
|
32317
|
+
name: "credentialStore",
|
|
32318
|
+
value: "createInMemoryWebAuthnCredentialStore()"
|
|
32319
|
+
},
|
|
32267
32320
|
{ name: "getUserId", value: "(user) => user.sub" },
|
|
32268
|
-
{
|
|
32321
|
+
{
|
|
32322
|
+
name: "getWebAuthnUser",
|
|
32323
|
+
value: TODO("resolve a stored credential userId back to a user")
|
|
32324
|
+
},
|
|
32269
32325
|
{ name: "origin", value: "'http://localhost:3000'" },
|
|
32270
32326
|
{ name: "rpId", value: "'localhost'" },
|
|
32271
32327
|
{ name: "rpName", value: "'YourApp'" },
|
|
@@ -32275,7 +32331,10 @@ var init_authScaffolds = __esm(() => {
|
|
|
32275
32331
|
}
|
|
32276
32332
|
],
|
|
32277
32333
|
generic: true,
|
|
32278
|
-
imports: [
|
|
32334
|
+
imports: [
|
|
32335
|
+
"createInMemoryWebAuthnCredentialStore",
|
|
32336
|
+
"type WebAuthnAdapter"
|
|
32337
|
+
],
|
|
32279
32338
|
note: "Provide a real `webauthnAdapter` wrapping a vetted library (e.g. @simplewebauthn/server); set origin/rpId/rpName for your domain.",
|
|
32280
32339
|
packages: [],
|
|
32281
32340
|
typeName: "WebAuthnConfig"
|
|
@@ -35207,8 +35266,7 @@ var IntegrationsPanel = ({
|
|
|
35207
35266
|
/* @__PURE__ */ jsx_dev_runtime6.jsxDEV("span", {
|
|
35208
35267
|
className: "dot"
|
|
35209
35268
|
}, undefined, false, undefined, this),
|
|
35210
|
-
"official Elysia plugins \u2014 install & wire from here or",
|
|
35211
|
-
" ",
|
|
35269
|
+
"official Elysia plugins \u2014 install & wire from here or ",
|
|
35212
35270
|
/* @__PURE__ */ jsx_dev_runtime6.jsxDEV("code", {
|
|
35213
35271
|
children: "absolute add"
|
|
35214
35272
|
}, undefined, false, undefined, this)
|
|
@@ -35232,7 +35290,8 @@ var IntegrationsPanel = ({
|
|
|
35232
35290
|
className: "section-files",
|
|
35233
35291
|
children: [
|
|
35234
35292
|
items.filter((item) => item.enabled).length,
|
|
35235
|
-
"
|
|
35293
|
+
" ",
|
|
35294
|
+
"enabled"
|
|
35236
35295
|
]
|
|
35237
35296
|
}, undefined, true, undefined, this)
|
|
35238
35297
|
]
|
|
@@ -35319,7 +35378,12 @@ var SettingRow = ({ busy, field, isSet, onSave, value }) => {
|
|
|
35319
35378
|
]
|
|
35320
35379
|
}, undefined, true, undefined, this);
|
|
35321
35380
|
};
|
|
35322
|
-
var FeatureCard = ({
|
|
35381
|
+
var FeatureCard = ({
|
|
35382
|
+
busy,
|
|
35383
|
+
feature,
|
|
35384
|
+
onScaffold,
|
|
35385
|
+
result
|
|
35386
|
+
}) => /* @__PURE__ */ jsx_dev_runtime7.jsxDEV("div", {
|
|
35323
35387
|
className: "rule",
|
|
35324
35388
|
children: [
|
|
35325
35389
|
/* @__PURE__ */ jsx_dev_runtime7.jsxDEV("div", {
|
|
@@ -35566,7 +35630,8 @@ var AuthPanel = ({ state: initial }) => {
|
|
|
35566
35630
|
/* @__PURE__ */ jsx_dev_runtime7.jsxDEV("code", {
|
|
35567
35631
|
children: "auth()"
|
|
35568
35632
|
}, undefined, false, undefined, this),
|
|
35569
|
-
" call to introspect \u2014 showing the full capability catalog as a reference. Features are configured in code where you call
|
|
35633
|
+
" call to introspect \u2014 showing the full capability catalog as a reference. Features are configured in code where you call",
|
|
35634
|
+
" ",
|
|
35570
35635
|
/* @__PURE__ */ jsx_dev_runtime7.jsxDEV("code", {
|
|
35571
35636
|
children: "auth()"
|
|
35572
35637
|
}, undefined, false, undefined, this),
|
|
@@ -35614,7 +35679,8 @@ var AuthPanel = ({ state: initial }) => {
|
|
|
35614
35679
|
configuredCount,
|
|
35615
35680
|
" of ",
|
|
35616
35681
|
state.features.length,
|
|
35617
|
-
"
|
|
35682
|
+
" ",
|
|
35683
|
+
"configured"
|
|
35618
35684
|
]
|
|
35619
35685
|
}, undefined, true, undefined, this)
|
|
35620
35686
|
]
|
|
@@ -35698,8 +35764,7 @@ var AuthPanel = ({ state: initial }) => {
|
|
|
35698
35764
|
/* @__PURE__ */ jsx_dev_runtime7.jsxDEV("p", {
|
|
35699
35765
|
className: "rule-desc",
|
|
35700
35766
|
children: [
|
|
35701
|
-
"Signing your own API/service tokens (not user login)? See",
|
|
35702
|
-
" ",
|
|
35767
|
+
"Signing your own API/service tokens (not user login)? See ",
|
|
35703
35768
|
/* @__PURE__ */ jsx_dev_runtime7.jsxDEV("code", {
|
|
35704
35769
|
children: "@elysiajs/jwt"
|
|
35705
35770
|
}, undefined, false, undefined, this),
|
package/dist/cli/index.js
CHANGED
|
@@ -172272,7 +172272,9 @@ var import_typescript3, VIRTUAL_NAME = "__absolute_type_introspect__.ts", MAX_DE
|
|
|
172272
172272
|
const candidates = specifier === "@absolutejs/absolute" ? [
|
|
172273
172273
|
resolve11(cwd, "node_modules", "@absolutejs", "absolute", "package.json"),
|
|
172274
172274
|
resolve11(cwd, "package.json")
|
|
172275
|
-
] : [
|
|
172275
|
+
] : [
|
|
172276
|
+
resolve11(cwd, "node_modules", ...specifier.split("/"), "package.json")
|
|
172277
|
+
];
|
|
172276
172278
|
for (const candidate of candidates) {
|
|
172277
172279
|
try {
|
|
172278
172280
|
const { version: version2 } = JSON.parse(readFileSync16(candidate, "utf-8"));
|
|
@@ -174055,7 +174057,10 @@ var init_authScaffolds = __esm(() => {
|
|
|
174055
174057
|
configKey: "compliance",
|
|
174056
174058
|
exportName: "complianceConfig",
|
|
174057
174059
|
fields: [
|
|
174058
|
-
{
|
|
174060
|
+
{
|
|
174061
|
+
name: "deleteUserData",
|
|
174062
|
+
value: TODO("erase or anonymize the user in your stores")
|
|
174063
|
+
},
|
|
174059
174064
|
{ name: "exportUserData", value: "async ({ user }) => ({})" },
|
|
174060
174065
|
{ name: "getUserId", value: "(user) => user.sub" }
|
|
174061
174066
|
],
|
|
@@ -174069,10 +174074,19 @@ var init_authScaffolds = __esm(() => {
|
|
|
174069
174074
|
configKey: "credentials",
|
|
174070
174075
|
exportName: "credentialsConfig",
|
|
174071
174076
|
fields: [
|
|
174072
|
-
{
|
|
174077
|
+
{
|
|
174078
|
+
name: "credentialStore",
|
|
174079
|
+
value: "createInMemoryCredentialStore()"
|
|
174080
|
+
},
|
|
174073
174081
|
{ name: "getUserByEmail", value: TODO("look up a user by email") },
|
|
174074
|
-
{
|
|
174075
|
-
|
|
174082
|
+
{
|
|
174083
|
+
name: "onCreateCredentialUser",
|
|
174084
|
+
value: TODO("create and return the user for identity.email")
|
|
174085
|
+
},
|
|
174086
|
+
{
|
|
174087
|
+
name: "onSendEmail",
|
|
174088
|
+
value: TODO("send the verification / reset email containing message.token")
|
|
174089
|
+
},
|
|
174076
174090
|
{ name: "requireEmailVerification", value: "false" }
|
|
174077
174091
|
],
|
|
174078
174092
|
generic: true,
|
|
@@ -174101,7 +174115,10 @@ var init_authScaffolds = __esm(() => {
|
|
|
174101
174115
|
fields: [
|
|
174102
174116
|
{ name: "mfaStore", value: "createInMemoryMfaStore()" },
|
|
174103
174117
|
{ name: "getUserId", value: "(user) => user.sub" },
|
|
174104
|
-
{
|
|
174118
|
+
{
|
|
174119
|
+
name: "getChallengeUser",
|
|
174120
|
+
value: TODO("resolve the parked challenge identity to a user")
|
|
174121
|
+
},
|
|
174105
174122
|
{ name: "issuer", value: "'YourApp'" }
|
|
174106
174123
|
],
|
|
174107
174124
|
generic: true,
|
|
@@ -174115,7 +174132,10 @@ var init_authScaffolds = __esm(() => {
|
|
|
174115
174132
|
exportName: "organizationsConfig",
|
|
174116
174133
|
fields: [
|
|
174117
174134
|
{ name: "getUserId", value: "(user) => user.sub" },
|
|
174118
|
-
{
|
|
174135
|
+
{
|
|
174136
|
+
name: "organizationStore",
|
|
174137
|
+
value: "createInMemoryOrganizationStore()"
|
|
174138
|
+
}
|
|
174119
174139
|
],
|
|
174120
174140
|
generic: true,
|
|
174121
174141
|
imports: ["createInMemoryOrganizationStore"],
|
|
@@ -174127,9 +174147,15 @@ var init_authScaffolds = __esm(() => {
|
|
|
174127
174147
|
configKey: "passwordless",
|
|
174128
174148
|
exportName: "passwordlessConfig",
|
|
174129
174149
|
fields: [
|
|
174130
|
-
{
|
|
174150
|
+
{
|
|
174151
|
+
name: "passwordlessTokenStore",
|
|
174152
|
+
value: "createInMemoryPasswordlessTokenStore()"
|
|
174153
|
+
},
|
|
174131
174154
|
{ name: "getUserByEmail", value: TODO("look up a user by email") },
|
|
174132
|
-
{
|
|
174155
|
+
{
|
|
174156
|
+
name: "onSendMagicLink",
|
|
174157
|
+
value: TODO("email the magic link containing message.token")
|
|
174158
|
+
}
|
|
174133
174159
|
],
|
|
174134
174160
|
generic: true,
|
|
174135
174161
|
imports: ["createInMemoryPasswordlessTokenStore"],
|
|
@@ -174141,7 +174167,10 @@ var init_authScaffolds = __esm(() => {
|
|
|
174141
174167
|
configKey: "portal",
|
|
174142
174168
|
exportName: "portalConfig",
|
|
174143
174169
|
fields: [
|
|
174144
|
-
{
|
|
174170
|
+
{
|
|
174171
|
+
name: "setupSessionStore",
|
|
174172
|
+
value: "createInMemorySetupSessionStore()"
|
|
174173
|
+
}
|
|
174145
174174
|
],
|
|
174146
174175
|
generic: false,
|
|
174147
174176
|
imports: ["createInMemorySetupSessionStore"],
|
|
@@ -174154,7 +174183,10 @@ var init_authScaffolds = __esm(() => {
|
|
|
174154
174183
|
exportName: "rolesConfig",
|
|
174155
174184
|
fields: [
|
|
174156
174185
|
{ name: "getUserId", value: "(user) => user.sub" },
|
|
174157
|
-
{
|
|
174186
|
+
{
|
|
174187
|
+
name: "organizationStore",
|
|
174188
|
+
value: "createInMemoryOrganizationStore()"
|
|
174189
|
+
},
|
|
174158
174190
|
{ name: "roleStore", value: "createInMemoryRoleStore()" }
|
|
174159
174191
|
],
|
|
174160
174192
|
generic: true,
|
|
@@ -174168,11 +174200,23 @@ var init_authScaffolds = __esm(() => {
|
|
|
174168
174200
|
exportName: "scimConfig",
|
|
174169
174201
|
fields: [
|
|
174170
174202
|
{ name: "scimTokenStore", value: "createInMemoryScimTokenStore()" },
|
|
174171
|
-
{
|
|
174203
|
+
{
|
|
174204
|
+
name: "getScimUser",
|
|
174205
|
+
value: TODO("return the SCIM user for { id, organizationId }")
|
|
174206
|
+
},
|
|
174172
174207
|
{ name: "listScimUsers", value: "async () => []" },
|
|
174173
|
-
{
|
|
174174
|
-
|
|
174175
|
-
|
|
174208
|
+
{
|
|
174209
|
+
name: "onScimUserCreate",
|
|
174210
|
+
value: TODO("create and return the SCIM user")
|
|
174211
|
+
},
|
|
174212
|
+
{
|
|
174213
|
+
name: "onScimUserDeactivate",
|
|
174214
|
+
value: TODO("deprovision the user (hard-delete or deactivate)")
|
|
174215
|
+
},
|
|
174216
|
+
{
|
|
174217
|
+
name: "onScimUserReplace",
|
|
174218
|
+
value: TODO("replace and return the SCIM user (undefined if unknown)")
|
|
174219
|
+
}
|
|
174176
174220
|
],
|
|
174177
174221
|
generic: false,
|
|
174178
174222
|
imports: ["createInMemoryScimTokenStore"],
|
|
@@ -174194,8 +174238,14 @@ var init_authScaffolds = __esm(() => {
|
|
|
174194
174238
|
configKey: "sso",
|
|
174195
174239
|
exportName: "ssoConfig",
|
|
174196
174240
|
fields: [
|
|
174197
|
-
{
|
|
174198
|
-
|
|
174241
|
+
{
|
|
174242
|
+
name: "ssoConnectionStore",
|
|
174243
|
+
value: "createInMemorySsoConnectionStore()"
|
|
174244
|
+
},
|
|
174245
|
+
{
|
|
174246
|
+
name: "getSsoUser",
|
|
174247
|
+
value: TODO("map the verified SSO identity to your user (create on first sign-in)")
|
|
174248
|
+
}
|
|
174199
174249
|
],
|
|
174200
174250
|
generic: true,
|
|
174201
174251
|
imports: ["createInMemorySsoConnectionStore"],
|
|
@@ -174207,9 +174257,15 @@ var init_authScaffolds = __esm(() => {
|
|
|
174207
174257
|
configKey: "webauthn",
|
|
174208
174258
|
exportName: "webauthnConfig",
|
|
174209
174259
|
fields: [
|
|
174210
|
-
{
|
|
174260
|
+
{
|
|
174261
|
+
name: "credentialStore",
|
|
174262
|
+
value: "createInMemoryWebAuthnCredentialStore()"
|
|
174263
|
+
},
|
|
174211
174264
|
{ name: "getUserId", value: "(user) => user.sub" },
|
|
174212
|
-
{
|
|
174265
|
+
{
|
|
174266
|
+
name: "getWebAuthnUser",
|
|
174267
|
+
value: TODO("resolve a stored credential userId back to a user")
|
|
174268
|
+
},
|
|
174213
174269
|
{ name: "origin", value: "'http://localhost:3000'" },
|
|
174214
174270
|
{ name: "rpId", value: "'localhost'" },
|
|
174215
174271
|
{ name: "rpName", value: "'YourApp'" },
|
|
@@ -174219,7 +174275,10 @@ var init_authScaffolds = __esm(() => {
|
|
|
174219
174275
|
}
|
|
174220
174276
|
],
|
|
174221
174277
|
generic: true,
|
|
174222
|
-
imports: [
|
|
174278
|
+
imports: [
|
|
174279
|
+
"createInMemoryWebAuthnCredentialStore",
|
|
174280
|
+
"type WebAuthnAdapter"
|
|
174281
|
+
],
|
|
174223
174282
|
note: "Provide a real `webauthnAdapter` wrapping a vetted library (e.g. @simplewebauthn/server); set origin/rpId/rpName for your domain.",
|
|
174224
174283
|
packages: [],
|
|
174225
174284
|
typeName: "WebAuthnConfig"
|
|
@@ -177927,7 +177986,10 @@ var DEFAULT_RELAY_PORT = 8787, DEFAULT_REQUEST_TIMEOUT_MS = 30000, headersToObje
|
|
|
177927
177986
|
open(ws) {
|
|
177928
177987
|
if (ws.data.control) {
|
|
177929
177988
|
client = ws;
|
|
177930
|
-
ws.send(encodeTunnelMessage({
|
|
177989
|
+
ws.send(encodeTunnelMessage({
|
|
177990
|
+
publicUrl: options.publicUrl ?? "",
|
|
177991
|
+
type: "ready"
|
|
177992
|
+
}));
|
|
177931
177993
|
return;
|
|
177932
177994
|
}
|
|
177933
177995
|
publicSockets.set(ws.data.id, ws);
|
|
@@ -177945,7 +178007,9 @@ var DEFAULT_RELAY_PORT = 8787, DEFAULT_REQUEST_TIMEOUT_MS = 30000, headersToObje
|
|
|
177945
178007
|
if (url.searchParams.get("token") !== options.token) {
|
|
177946
178008
|
return new Response("Forbidden", { status: 403 });
|
|
177947
178009
|
}
|
|
177948
|
-
const upgraded = srv.upgrade(request, {
|
|
178010
|
+
const upgraded = srv.upgrade(request, {
|
|
178011
|
+
data: { control: true }
|
|
178012
|
+
});
|
|
177949
178013
|
return upgraded ? undefined : new Response("Upgrade failed", { status: 426 });
|
|
177950
178014
|
}
|
|
177951
178015
|
if (!client) {
|
|
@@ -177983,7 +178047,9 @@ var DEFAULT_RELAY_PORT = 8787, DEFAULT_REQUEST_TIMEOUT_MS = 30000, headersToObje
|
|
|
177983
178047
|
const result = await Promise.race([responsePromise, timeout]);
|
|
177984
178048
|
pending.delete(id);
|
|
177985
178049
|
if (result.type === "error") {
|
|
177986
|
-
return new Response(`Tunnel error: ${result.message}`, {
|
|
178050
|
+
return new Response(`Tunnel error: ${result.message}`, {
|
|
178051
|
+
status: 504
|
|
178052
|
+
});
|
|
177987
178053
|
}
|
|
177988
178054
|
if (result.type !== "response") {
|
|
177989
178055
|
return new Response("Tunnel protocol error", { status: 502 });
|
|
@@ -178040,7 +178106,12 @@ var controlSocketUrl = (relayUrl, token) => {
|
|
|
178040
178106
|
url.search = `?token=${encodeURIComponent(token)}`;
|
|
178041
178107
|
return url.toString();
|
|
178042
178108
|
};
|
|
178043
|
-
var STRIPPED_REQUEST_HEADERS = new Set([
|
|
178109
|
+
var STRIPPED_REQUEST_HEADERS = new Set([
|
|
178110
|
+
"host",
|
|
178111
|
+
"connection",
|
|
178112
|
+
"content-length",
|
|
178113
|
+
TUNNEL_FORWARDED_HOST_HEADER
|
|
178114
|
+
]);
|
|
178044
178115
|
var startTunnelClient = (options) => {
|
|
178045
178116
|
const publicUrl = options.relayUrl.replace(/\/$/, "");
|
|
178046
178117
|
const localWsOrigin = options.localOrigin.replace(/^http/, "ws");
|
|
@@ -178084,7 +178155,12 @@ var startTunnelClient = (options) => {
|
|
|
178084
178155
|
});
|
|
178085
178156
|
local.addEventListener("error", () => {
|
|
178086
178157
|
if (!entry.ready) {
|
|
178087
|
-
socket?.send(encodeTunnelMessage({
|
|
178158
|
+
socket?.send(encodeTunnelMessage({
|
|
178159
|
+
error: "local ws failed",
|
|
178160
|
+
id,
|
|
178161
|
+
ok: false,
|
|
178162
|
+
type: "ws_open_ack"
|
|
178163
|
+
}));
|
|
178088
178164
|
}
|
|
178089
178165
|
});
|
|
178090
178166
|
};
|
package/dist/client/index.js.map
CHANGED
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
"import type { IslandFramework } from '../../types/island';\nimport {\n\tgetIslandManifestEntries,\n\tgetIslandManifestKey\n} from '../core/islandManifest';\n\nexport const createIslandManifestResolver = (\n\tmanifest: Record<string, string>\n) => {\n\tconst islandManifest = getIslandManifestEntries(manifest);\n\n\treturn async (framework: IslandFramework, component: string) => {\n\t\tconst modulePath =\n\t\t\tislandManifest[framework]?.[component] ??\n\t\t\tmanifest[getIslandManifestKey(framework, component)];\n\t\tif (!modulePath) return undefined;\n\n\t\tconst loadedModule = await import(modulePath);\n\n\t\treturn loadedModule.default;\n\t};\n};\n",
|
|
22
22
|
"const createStoreImpl = (createState) => {\n let state;\n const listeners = /* @__PURE__ */ new Set();\n const setState = (partial, replace) => {\n const nextState = typeof partial === \"function\" ? partial(state) : partial;\n if (!Object.is(nextState, state)) {\n const previousState = state;\n state = (replace != null ? replace : typeof nextState !== \"object\" || nextState === null) ? nextState : Object.assign({}, state, nextState);\n listeners.forEach((listener) => listener(state, previousState));\n }\n };\n const getState = () => state;\n const getInitialState = () => initialState;\n const subscribe = (listener) => {\n listeners.add(listener);\n return () => listeners.delete(listener);\n };\n const api = { setState, getState, getInitialState, subscribe };\n const initialState = state = createState(setState, getState, api);\n return api;\n};\nconst createStore = ((createState) => createState ? createStoreImpl(createState) : createStoreImpl);\n\nexport { createStore };\n",
|
|
23
23
|
"const reduxImpl = (reducer, initial) => (set, _get, api) => {\n api.dispatch = (action) => {\n set((state) => reducer(state, action), false, action);\n return action;\n };\n api.dispatchFromDevtools = true;\n return { dispatch: (...args) => api.dispatch(...args), ...initial };\n};\nconst redux = reduxImpl;\n\nconst shouldDispatchFromDevtools = (api) => !!api.dispatchFromDevtools && typeof api.dispatch === \"function\";\nconst trackedConnections = /* @__PURE__ */ new Map();\nconst getTrackedConnectionState = (name) => {\n const api = trackedConnections.get(name);\n if (!api) return {};\n return Object.fromEntries(\n Object.entries(api.stores).map(([key, api2]) => [key, api2.getState()])\n );\n};\nconst extractConnectionInformation = (store, extensionConnector, options) => {\n if (store === void 0) {\n return {\n type: \"untracked\",\n connection: extensionConnector.connect(options)\n };\n }\n const existingConnection = trackedConnections.get(options.name);\n if (existingConnection) {\n return { type: \"tracked\", store, ...existingConnection };\n }\n const newConnection = {\n connection: extensionConnector.connect(options),\n stores: {}\n };\n trackedConnections.set(options.name, newConnection);\n return { type: \"tracked\", store, ...newConnection };\n};\nconst removeStoreFromTrackedConnections = (name, store) => {\n if (store === void 0) return;\n const connectionInfo = trackedConnections.get(name);\n if (!connectionInfo) return;\n delete connectionInfo.stores[store];\n if (Object.keys(connectionInfo.stores).length === 0) {\n trackedConnections.delete(name);\n }\n};\nconst findCallerName = (stack) => {\n var _a, _b;\n if (!stack) return void 0;\n const traceLines = stack.split(\"\\n\");\n const apiSetStateLineIndex = traceLines.findIndex(\n (traceLine) => traceLine.includes(\"api.setState\")\n );\n if (apiSetStateLineIndex < 0) return void 0;\n const callerLine = ((_a = traceLines[apiSetStateLineIndex + 1]) == null ? void 0 : _a.trim()) || \"\";\n return (_b = /.+ (.+) .+/.exec(callerLine)) == null ? void 0 : _b[1];\n};\nconst devtoolsImpl = (fn, devtoolsOptions = {}) => (set, get, api) => {\n const { enabled, anonymousActionType, store, ...options } = devtoolsOptions;\n let extensionConnector;\n try {\n extensionConnector = (enabled != null ? enabled : (import.meta.env ? import.meta.env.MODE : void 0) !== \"production\") && window.__REDUX_DEVTOOLS_EXTENSION__;\n } catch (e) {\n }\n if (!extensionConnector) {\n return fn(set, get, api);\n }\n const { connection, ...connectionInformation } = extractConnectionInformation(store, extensionConnector, options);\n let isRecording = true;\n api.setState = ((state, replace, nameOrAction) => {\n const r = set(state, replace);\n if (!isRecording) return r;\n const action = nameOrAction === void 0 ? {\n type: anonymousActionType || findCallerName(new Error().stack) || \"anonymous\"\n } : typeof nameOrAction === \"string\" ? { type: nameOrAction } : nameOrAction;\n if (store === void 0) {\n connection == null ? void 0 : connection.send(action, get());\n return r;\n }\n connection == null ? void 0 : connection.send(\n {\n ...action,\n type: `${store}/${action.type}`\n },\n {\n ...getTrackedConnectionState(options.name),\n [store]: api.getState()\n }\n );\n return r;\n });\n api.devtools = {\n cleanup: () => {\n if (connection && typeof connection.unsubscribe === \"function\") {\n connection.unsubscribe();\n }\n removeStoreFromTrackedConnections(options.name, store);\n }\n };\n const setStateFromDevtools = (...a) => {\n const originalIsRecording = isRecording;\n isRecording = false;\n set(...a);\n isRecording = originalIsRecording;\n };\n const initialState = fn(api.setState, get, api);\n if (connectionInformation.type === \"untracked\") {\n connection == null ? void 0 : connection.init(initialState);\n } else {\n connectionInformation.stores[connectionInformation.store] = api;\n connection == null ? void 0 : connection.init(\n Object.fromEntries(\n Object.entries(connectionInformation.stores).map(([key, store2]) => [\n key,\n key === connectionInformation.store ? initialState : store2.getState()\n ])\n )\n );\n }\n if (shouldDispatchFromDevtools(api)) {\n let didWarnAboutReservedActionType = false;\n const originalDispatch = api.dispatch;\n api.dispatch = (...args) => {\n if ((import.meta.env ? import.meta.env.MODE : void 0) !== \"production\" && args[0].type === \"__setState\" && !didWarnAboutReservedActionType) {\n console.warn(\n '[zustand devtools middleware] \"__setState\" action type is reserved to set state from the devtools. Avoid using it.'\n );\n didWarnAboutReservedActionType = true;\n }\n originalDispatch(...args);\n };\n }\n connection.subscribe((message) => {\n var _a;\n switch (message.type) {\n case \"ACTION\":\n if (typeof message.payload !== \"string\") {\n console.error(\n \"[zustand devtools middleware] Unsupported action format\"\n );\n return;\n }\n return parseJsonThen(\n message.payload,\n (action) => {\n if (action.type === \"__setState\") {\n if (store === void 0) {\n setStateFromDevtools(action.state);\n return;\n }\n if (Object.keys(action.state).length !== 1) {\n console.error(\n `\n [zustand devtools middleware] Unsupported __setState action format.\n When using 'store' option in devtools(), the 'state' should have only one key, which is a value of 'store' that was passed in devtools(),\n and value of this only key should be a state object. Example: { \"type\": \"__setState\", \"state\": { \"abc123Store\": { \"foo\": \"bar\" } } }\n `\n );\n }\n const stateFromDevtools = action.state[store];\n if (stateFromDevtools === void 0 || stateFromDevtools === null) {\n return;\n }\n if (JSON.stringify(api.getState()) !== JSON.stringify(stateFromDevtools)) {\n setStateFromDevtools(stateFromDevtools);\n }\n return;\n }\n if (shouldDispatchFromDevtools(api)) {\n api.dispatch(action);\n }\n }\n );\n case \"DISPATCH\":\n switch (message.payload.type) {\n case \"RESET\":\n setStateFromDevtools(initialState);\n if (store === void 0) {\n return connection == null ? void 0 : connection.init(api.getState());\n }\n return connection == null ? void 0 : connection.init(getTrackedConnectionState(options.name));\n case \"COMMIT\":\n if (store === void 0) {\n connection == null ? void 0 : connection.init(api.getState());\n return;\n }\n return connection == null ? void 0 : connection.init(getTrackedConnectionState(options.name));\n case \"ROLLBACK\":\n return parseJsonThen(message.state, (state) => {\n if (store === void 0) {\n setStateFromDevtools(state);\n connection == null ? void 0 : connection.init(api.getState());\n return;\n }\n setStateFromDevtools(state[store]);\n connection == null ? void 0 : connection.init(getTrackedConnectionState(options.name));\n });\n case \"JUMP_TO_STATE\":\n case \"JUMP_TO_ACTION\":\n return parseJsonThen(message.state, (state) => {\n if (store === void 0) {\n setStateFromDevtools(state);\n return;\n }\n if (JSON.stringify(api.getState()) !== JSON.stringify(state[store])) {\n setStateFromDevtools(state[store]);\n }\n });\n case \"IMPORT_STATE\": {\n const { nextLiftedState } = message.payload;\n const lastComputedState = (_a = nextLiftedState.computedStates.slice(-1)[0]) == null ? void 0 : _a.state;\n if (!lastComputedState) return;\n if (store === void 0) {\n setStateFromDevtools(lastComputedState);\n } else {\n setStateFromDevtools(lastComputedState[store]);\n }\n connection == null ? void 0 : connection.send(\n null,\n // FIXME no-any\n nextLiftedState\n );\n return;\n }\n case \"PAUSE_RECORDING\":\n return isRecording = !isRecording;\n }\n return;\n }\n });\n return initialState;\n};\nconst devtools = devtoolsImpl;\nconst parseJsonThen = (stringified, fn) => {\n let parsed;\n try {\n parsed = JSON.parse(stringified);\n } catch (e) {\n console.error(\n \"[zustand devtools middleware] Could not parse the received json\",\n e\n );\n }\n if (parsed !== void 0) fn(parsed);\n};\n\nconst subscribeWithSelectorImpl = (fn) => (set, get, api) => {\n const origSubscribe = api.subscribe;\n api.subscribe = ((selector, optListener, options) => {\n let listener = selector;\n if (optListener) {\n const equalityFn = (options == null ? void 0 : options.equalityFn) || Object.is;\n let currentSlice = selector(api.getState());\n listener = (state) => {\n const nextSlice = selector(state);\n if (!equalityFn(currentSlice, nextSlice)) {\n const previousSlice = currentSlice;\n optListener(currentSlice = nextSlice, previousSlice);\n }\n };\n if (options == null ? void 0 : options.fireImmediately) {\n optListener(currentSlice, currentSlice);\n }\n }\n return origSubscribe(listener);\n });\n const initialState = fn(set, get, api);\n return initialState;\n};\nconst subscribeWithSelector = subscribeWithSelectorImpl;\n\nfunction combine(initialState, create) {\n return (...args) => Object.assign({}, initialState, create(...args));\n}\n\nfunction createJSONStorage(getStorage, options) {\n let storage;\n try {\n storage = getStorage();\n } catch (e) {\n return;\n }\n const persistStorage = {\n getItem: (name) => {\n var _a;\n const parse = (str2) => {\n if (str2 === null) {\n return null;\n }\n return JSON.parse(str2, options == null ? void 0 : options.reviver);\n };\n const str = (_a = storage.getItem(name)) != null ? _a : null;\n if (str instanceof Promise) {\n return str.then(parse);\n }\n return parse(str);\n },\n setItem: (name, newValue) => storage.setItem(name, JSON.stringify(newValue, options == null ? void 0 : options.replacer)),\n removeItem: (name) => storage.removeItem(name)\n };\n return persistStorage;\n}\nconst toThenable = (fn) => (input) => {\n try {\n const result = fn(input);\n if (result instanceof Promise) {\n return result;\n }\n return {\n then(onFulfilled) {\n return toThenable(onFulfilled)(result);\n },\n catch(_onRejected) {\n return this;\n }\n };\n } catch (e) {\n return {\n then(_onFulfilled) {\n return this;\n },\n catch(onRejected) {\n return toThenable(onRejected)(e);\n }\n };\n }\n};\nconst persistImpl = (config, baseOptions) => (set, get, api) => {\n let options = {\n storage: createJSONStorage(() => window.localStorage),\n partialize: (state) => state,\n version: 0,\n merge: (persistedState, currentState) => ({\n ...currentState,\n ...persistedState\n }),\n ...baseOptions\n };\n let hasHydrated = false;\n let hydrationVersion = 0;\n const hydrationListeners = /* @__PURE__ */ new Set();\n const finishHydrationListeners = /* @__PURE__ */ new Set();\n let storage = options.storage;\n if (!storage) {\n return config(\n (...args) => {\n console.warn(\n `[zustand persist middleware] Unable to update item '${options.name}', the given storage is currently unavailable.`\n );\n set(...args);\n },\n get,\n api\n );\n }\n const setItem = () => {\n const state = options.partialize({ ...get() });\n return storage.setItem(options.name, {\n state,\n version: options.version\n });\n };\n const savedSetState = api.setState;\n api.setState = (state, replace) => {\n savedSetState(state, replace);\n return setItem();\n };\n const configResult = config(\n (...args) => {\n set(...args);\n return setItem();\n },\n get,\n api\n );\n api.getInitialState = () => configResult;\n let stateFromStorage;\n const hydrate = () => {\n var _a, _b;\n if (!storage) return;\n const currentVersion = ++hydrationVersion;\n hasHydrated = false;\n hydrationListeners.forEach((cb) => {\n var _a2;\n return cb((_a2 = get()) != null ? _a2 : configResult);\n });\n const postRehydrationCallback = ((_b = options.onRehydrateStorage) == null ? void 0 : _b.call(options, (_a = get()) != null ? _a : configResult)) || void 0;\n return toThenable(storage.getItem.bind(storage))(options.name).then((deserializedStorageValue) => {\n if (deserializedStorageValue) {\n if (typeof deserializedStorageValue.version === \"number\" && deserializedStorageValue.version !== options.version) {\n if (options.migrate) {\n const migration = options.migrate(\n deserializedStorageValue.state,\n deserializedStorageValue.version\n );\n if (migration instanceof Promise) {\n return migration.then((result) => [true, result]);\n }\n return [true, migration];\n }\n console.error(\n `State loaded from storage couldn't be migrated since no migrate function was provided`\n );\n } else {\n return [false, deserializedStorageValue.state];\n }\n }\n return [false, void 0];\n }).then((migrationResult) => {\n var _a2;\n if (currentVersion !== hydrationVersion) {\n return;\n }\n const [migrated, migratedState] = migrationResult;\n stateFromStorage = options.merge(\n migratedState,\n (_a2 = get()) != null ? _a2 : configResult\n );\n set(stateFromStorage, true);\n if (migrated) {\n return setItem();\n }\n }).then(() => {\n if (currentVersion !== hydrationVersion) {\n return;\n }\n postRehydrationCallback == null ? void 0 : postRehydrationCallback(get(), void 0);\n stateFromStorage = get();\n hasHydrated = true;\n finishHydrationListeners.forEach((cb) => cb(stateFromStorage));\n }).catch((e) => {\n if (currentVersion !== hydrationVersion) {\n return;\n }\n postRehydrationCallback == null ? void 0 : postRehydrationCallback(void 0, e);\n });\n };\n api.persist = {\n setOptions: (newOptions) => {\n options = {\n ...options,\n ...newOptions\n };\n if (newOptions.storage) {\n storage = newOptions.storage;\n }\n },\n clearStorage: () => {\n storage == null ? void 0 : storage.removeItem(options.name);\n },\n getOptions: () => options,\n rehydrate: () => hydrate(),\n hasHydrated: () => hasHydrated,\n onHydrate: (cb) => {\n hydrationListeners.add(cb);\n return () => {\n hydrationListeners.delete(cb);\n };\n },\n onFinishHydration: (cb) => {\n finishHydrationListeners.add(cb);\n return () => {\n finishHydrationListeners.delete(cb);\n };\n }\n };\n if (!options.skipHydration) {\n hydrate();\n }\n return stateFromStorage || configResult;\n};\nconst persist = persistImpl;\n\nfunction ssrSafe(config, isSSR = typeof window === \"undefined\") {\n return (set, get, api) => {\n if (!isSSR) {\n return config(set, get, api);\n }\n const ssrSet = () => {\n throw new Error(\"Cannot set state of Zustand store in SSR\");\n };\n api.setState = ssrSet;\n return config(ssrSet, get, api);\n };\n}\n\nexport { combine, createJSONStorage, devtools, persist, redux, subscribeWithSelector, ssrSafe as unstable_ssrSafe };\n",
|
|
24
|
-
"import { createStore, type StateCreator, type StoreApi } from 'zustand/vanilla';\nimport { combine } from 'zustand/middleware';\n\nexport type IslandStoreState = object;\ntype IslandStoreSnapshot = Record<string, unknown>;\ntype IslandStoreShape<\n\tTState extends IslandStoreState,\n\tTActions extends object\n> = Omit<TState, keyof TActions> & TActions;\nexport type IslandStateSnapshot = Record<string, IslandStoreSnapshot>;\ntype AnyIslandStore = StoreApi<object>;\ntype IslandStoreInstance = {\n\tapplyExternalSnapshot: (snapshot: IslandStoreSnapshot) => void;\n\tstore: AnyIslandStore;\n};\n\nexport const ABSOLUTE_ISLAND_STATE = '__ABS_ISLAND_STATE__';\nexport const ABSOLUTE_ISLAND_STORES = '__ABS_ISLAND_STORES__';\n\ndeclare global {\n\tvar __ABS_ISLAND_STATE__: IslandStateSnapshot | undefined;\n\tvar __ABS_ISLAND_STORES__:\n\t\t| Map<string, Set<IslandStoreInstance>>\n\t\t| undefined;\n}\n\nconst getIslandStoreSnapshot = () => {\n\tglobalThis.__ABS_ISLAND_STATE__ ??= {};\n\n\treturn globalThis.__ABS_ISLAND_STATE__;\n};\n\nconst getIslandStores = () => {\n\tglobalThis.__ABS_ISLAND_STORES__ ??= new Map();\n\n\treturn globalThis.__ABS_ISLAND_STORES__;\n};\n\nconst isSerializableValue = (value: unknown) =>\n\ttypeof value !== 'function' && value !== undefined;\n\nconst toSerializableState = <T extends object>(state: T) =>\n\tObject.fromEntries(\n\t\tObject.entries(state).filter(([, value]) => isSerializableValue(value))\n\t);\n\nconst applySnapshot = <T extends object>(\n\tstore: StoreApi<T>,\n\tsnapshot: IslandStoreSnapshot | undefined\n) => {\n\tif (!snapshot) {\n\t\treturn;\n\t}\n\n\tstore.setState({\n\t\t...store.getState(),\n\t\t...snapshot\n\t});\n};\n\nconst getPeerStores = (\n\tstoreInstances: Set<IslandStoreInstance>,\n\townerStore: AnyIslandStore\n) => [...storeInstances].filter((peer) => peer.store !== ownerStore);\n\nconst syncIslandSnapshot = <\n\tTState extends IslandStoreState,\n\tTActions extends object\n>(\n\tstoreId: string,\n\tstate: IslandStoreShape<TState, TActions>,\n\tstoreInstances: Set<IslandStoreInstance>,\n\townerStore: AnyIslandStore\n) => {\n\tconst nextSnapshot = toSerializableState(state);\n\tgetIslandStoreSnapshot()[storeId] = nextSnapshot;\n\n\tfor (const peerStore of getPeerStores(storeInstances, ownerStore)) {\n\t\tpeerStore.applyExternalSnapshot(nextSnapshot);\n\t}\n};\n\nexport const createIslandStore = <\n\tTState extends IslandStoreState,\n\tTActions extends object\n>(\n\tstoreId: string,\n\tinitialState: TState,\n\tcreateState: StateCreator<TState, [], [], TActions>\n) => {\n\tconst store = createStore(combine(initialState, createState));\n\tconst stores = getIslandStores();\n\tconst storeInstances =\n\t\tstores.get(storeId) ?? new Set<IslandStoreInstance>();\n\tconst initialSnapshot = getIslandStoreSnapshot()[storeId];\n\tapplySnapshot(store, initialSnapshot);\n\tlet isApplyingExternalSnapshot = false;\n\n\tconst applyExternalSnapshot = (snapshot: IslandStoreSnapshot) => {\n\t\tisApplyingExternalSnapshot = true;\n\t\tapplySnapshot(store, snapshot);\n\t};\n\n\tstoreInstances.add({\n\t\tapplyExternalSnapshot,\n\t\tstore\n\t});\n\tstores.set(storeId, storeInstances);\n\n\tsyncIslandSnapshot(storeId, store.getState(), storeInstances, store);\n\tstore.subscribe((state) => {\n\t\tif (isApplyingExternalSnapshot) {\n\t\t\tisApplyingExternalSnapshot = false;\n\n\t\t\treturn;\n\t\t}\n\n\t\tsyncIslandSnapshot(storeId, state, storeInstances, store);\n\t});\n\n\treturn store;\n};\nexport const getIslandStoreServerSnapshot = <\n\tTState extends IslandStoreState,\n\tTSelected\n>(\n\tstore: StoreApi<TState>,\n\tselector: (state: TState) => TSelected\n) => selector(store.getInitialState());\nconst applySnapshotToStoreInstances = (\n\tstoreId: string,\n\tinstances: Set<IslandStoreInstance>,\n\tsnapshot: IslandStateSnapshot\n) => {\n\tfor (const instance of instances) {\n\t\tinstance.applyExternalSnapshot(snapshot[storeId] ?? {});\n\t}\n};\n\nexport const initializeIslandStores = (state: IslandStateSnapshot) => {\n\tconst currentSnapshot = getIslandStoreSnapshot();\n\tconst nextSnapshot: IslandStateSnapshot = {\n\t\t...state,\n\t\t...currentSnapshot\n\t};\n\n\tglobalThis.__ABS_ISLAND_STATE__ = nextSnapshot;\n\n\tfor (const [storeId, store] of getIslandStores()) {\n\t\tapplySnapshotToStoreInstances(storeId, store, nextSnapshot);\n\t}\n};\nexport const readIslandStore = <TState extends IslandStoreState, TSelected>(\n\tstore: StoreApi<TState>,\n\tselector: (state: TState) => TSelected\n) => selector(store.getState());\nexport const resetIslandStoreForTesting = () => {\n\tdelete globalThis.__ABS_ISLAND_STATE__;\n\tdelete globalThis.__ABS_ISLAND_STORES__;\n};\nexport const subscribeIslandStore = <\n\tTState extends IslandStoreState,\n\tTSelected\n>(\n\tstore: StoreApi<TState>,\n\tselector: (state: TState) => TSelected,\n\tlistener: (value: TSelected) => void\n) => {\n\tlet currentSelection = selector(store.getState());\n\n\treturn store.subscribe((state) => {\n\t\tconst nextSelection = selector(state);\n\t\tif (Object.is(nextSelection, currentSelection)) {\n\t\t\treturn;\n\t\t}\n\n\t\tcurrentSelection = nextSelection;\n\t\tlistener(nextSelection);\n\t});\n};\n
|
|
24
|
+
"import { createStore, type StateCreator, type StoreApi } from 'zustand/vanilla';\nimport { combine } from 'zustand/middleware';\n\nexport type IslandStoreState = object;\ntype IslandStoreSnapshot = Record<string, unknown>;\ntype IslandStoreShape<\n\tTState extends IslandStoreState,\n\tTActions extends object\n> = Omit<TState, keyof TActions> & TActions;\nexport type IslandStateSnapshot = Record<string, IslandStoreSnapshot>;\ntype AnyIslandStore = StoreApi<object>;\ntype IslandStoreInstance = {\n\tapplyExternalSnapshot: (snapshot: IslandStoreSnapshot) => void;\n\tstore: AnyIslandStore;\n};\n\nexport const ABSOLUTE_ISLAND_STATE = '__ABS_ISLAND_STATE__';\nexport const ABSOLUTE_ISLAND_STORES = '__ABS_ISLAND_STORES__';\n\ndeclare global {\n\tvar __ABS_ISLAND_STATE__: IslandStateSnapshot | undefined;\n\tvar __ABS_ISLAND_STORES__:\n\t\t| Map<string, Set<IslandStoreInstance>>\n\t\t| undefined;\n}\n\nconst getIslandStoreSnapshot = () => {\n\tglobalThis.__ABS_ISLAND_STATE__ ??= {};\n\n\treturn globalThis.__ABS_ISLAND_STATE__;\n};\n\nconst getIslandStores = () => {\n\tglobalThis.__ABS_ISLAND_STORES__ ??= new Map();\n\n\treturn globalThis.__ABS_ISLAND_STORES__;\n};\n\nconst isSerializableValue = (value: unknown) =>\n\ttypeof value !== 'function' && value !== undefined;\n\nconst toSerializableState = <T extends object>(state: T) =>\n\tObject.fromEntries(\n\t\tObject.entries(state).filter(([, value]) => isSerializableValue(value))\n\t);\n\nconst applySnapshot = <T extends object>(\n\tstore: StoreApi<T>,\n\tsnapshot: IslandStoreSnapshot | undefined\n) => {\n\tif (!snapshot) {\n\t\treturn;\n\t}\n\n\tstore.setState({\n\t\t...store.getState(),\n\t\t...snapshot\n\t});\n};\n\nconst getPeerStores = (\n\tstoreInstances: Set<IslandStoreInstance>,\n\townerStore: AnyIslandStore\n) => [...storeInstances].filter((peer) => peer.store !== ownerStore);\n\nconst syncIslandSnapshot = <\n\tTState extends IslandStoreState,\n\tTActions extends object\n>(\n\tstoreId: string,\n\tstate: IslandStoreShape<TState, TActions>,\n\tstoreInstances: Set<IslandStoreInstance>,\n\townerStore: AnyIslandStore\n) => {\n\tconst nextSnapshot = toSerializableState(state);\n\tgetIslandStoreSnapshot()[storeId] = nextSnapshot;\n\n\tfor (const peerStore of getPeerStores(storeInstances, ownerStore)) {\n\t\tpeerStore.applyExternalSnapshot(nextSnapshot);\n\t}\n};\n\nexport const createIslandStore = <\n\tTState extends IslandStoreState,\n\tTActions extends object\n>(\n\tstoreId: string,\n\tinitialState: TState,\n\tcreateState: StateCreator<TState, [], [], TActions>\n) => {\n\tconst store = createStore(combine(initialState, createState));\n\tconst stores = getIslandStores();\n\tconst storeInstances =\n\t\tstores.get(storeId) ?? new Set<IslandStoreInstance>();\n\tconst initialSnapshot = getIslandStoreSnapshot()[storeId];\n\tapplySnapshot(store, initialSnapshot);\n\tlet isApplyingExternalSnapshot = false;\n\n\tconst applyExternalSnapshot = (snapshot: IslandStoreSnapshot) => {\n\t\tisApplyingExternalSnapshot = true;\n\t\tapplySnapshot(store, snapshot);\n\t};\n\n\tstoreInstances.add({\n\t\tapplyExternalSnapshot,\n\t\tstore\n\t});\n\tstores.set(storeId, storeInstances);\n\n\tsyncIslandSnapshot(storeId, store.getState(), storeInstances, store);\n\tstore.subscribe((state) => {\n\t\tif (isApplyingExternalSnapshot) {\n\t\t\tisApplyingExternalSnapshot = false;\n\n\t\t\treturn;\n\t\t}\n\n\t\tsyncIslandSnapshot(storeId, state, storeInstances, store);\n\t});\n\n\treturn store;\n};\nexport const getIslandStoreServerSnapshot = <\n\tTState extends IslandStoreState,\n\tTSelected\n>(\n\tstore: StoreApi<TState>,\n\tselector: (state: TState) => TSelected\n) => selector(store.getInitialState());\nconst applySnapshotToStoreInstances = (\n\tstoreId: string,\n\tinstances: Set<IslandStoreInstance>,\n\tsnapshot: IslandStateSnapshot\n) => {\n\tfor (const instance of instances) {\n\t\tinstance.applyExternalSnapshot(snapshot[storeId] ?? {});\n\t}\n};\n\nexport const initializeIslandStores = (state: IslandStateSnapshot) => {\n\tconst currentSnapshot = getIslandStoreSnapshot();\n\tconst nextSnapshot: IslandStateSnapshot = {\n\t\t...state,\n\t\t...currentSnapshot\n\t};\n\n\tglobalThis.__ABS_ISLAND_STATE__ = nextSnapshot;\n\n\tfor (const [storeId, store] of getIslandStores()) {\n\t\tapplySnapshotToStoreInstances(storeId, store, nextSnapshot);\n\t}\n};\nexport const readIslandStore = <TState extends IslandStoreState, TSelected>(\n\tstore: StoreApi<TState>,\n\tselector: (state: TState) => TSelected\n) => selector(store.getState());\nexport const resetIslandStoreForTesting = () => {\n\tdelete globalThis.__ABS_ISLAND_STATE__;\n\tdelete globalThis.__ABS_ISLAND_STORES__;\n};\nexport const subscribeIslandStore = <\n\tTState extends IslandStoreState,\n\tTSelected\n>(\n\tstore: StoreApi<TState>,\n\tselector: (state: TState) => TSelected,\n\tlistener: (value: TSelected) => void\n) => {\n\tlet currentSelection = selector(store.getState());\n\n\treturn store.subscribe((state) => {\n\t\tconst nextSelection = selector(state);\n\t\tif (Object.is(nextSelection, currentSelection)) {\n\t\t\treturn;\n\t\t}\n\n\t\tcurrentSelection = nextSelection;\n\t\tlistener(nextSelection);\n\t});\n};\n",
|
|
25
25
|
"import type { IslandFramework } from '../../types/island';\nimport { getIslandComponent, parseIslandProps } from '../core/islands';\nimport { initializeIslandMarkupSnapshot } from './preserveIslandMarkup';\n\ninitializeIslandMarkupSnapshot();\n\ntype RuntimeIslandRegistry = Partial<\n\tRecord<IslandFramework, Record<string, unknown>>\n>;\n\ntype StartIslandsOptions = {\n\tregistry: RuntimeIslandRegistry;\n\tresolveComponent?: (\n\t\tframework: IslandFramework,\n\t\tcomponent: string\n\t) => Promise<unknown>;\n\troot?: ParentNode & Node;\n};\n\ntype IslandElement = HTMLElement & {\n\tdataset: DOMStringMap & {\n\t\tcomponent?: string;\n\t\terror?: string;\n\t\tframework?: IslandFramework;\n\t\thydrate?: string;\n\t\tislandId?: string;\n\t\tprops?: string;\n\t};\n};\n\nconst idleDeadline: IdleDeadline = {\n\tdidTimeout: false,\n\ttimeRemaining: () => 0\n};\n\nconst requestIdle =\n\ttypeof window !== 'undefined' && 'requestIdleCallback' in window\n\t\t? window.requestIdleCallback.bind(window)\n\t\t: (callback: IdleRequestCallback) =>\n\t\t\t\twindow.setTimeout(() => callback(idleDeadline), 1);\n\nconst isPropsRecord = (value: unknown): value is Record<string, unknown> =>\n\ttypeof value === 'object' && value !== null;\n\nconst isIslandElement = (value: EventTarget | null): value is IslandElement =>\n\tvalue instanceof HTMLElement && value.dataset.island === 'true';\n\nconst observedRoots = new WeakSet<Node>();\nconst hydratingIslands = new WeakSet<HTMLElement>();\n\n// Framework-specific hydrators are dynamic-imported on first use so the\n// island runtime never statically pulls in a framework's runtime (and its\n// transitive deps) the consumer doesn't actually use. Without this, a\n// React-only project loading `@absolutejs/absolute/client` would resolve\n// every framework's peer deps — including `@angular/core` — and fail at\n// module load if any of them weren't installed.\nconst hydrateByFramework = async (\n\tregistry: RuntimeIslandRegistry,\n\tframework: IslandFramework,\n\tcomponentName: string,\n\telement: IslandElement,\n\tprops: unknown,\n\tresolveComponent?: (\n\t\tframework: IslandFramework,\n\t\tcomponent: string\n\t) => Promise<unknown>\n) => {\n\tconst propsRecord = isPropsRecord(props) ? props : undefined;\n\n\tif (framework === 'react') {\n\t\tconst { hydrateReactIsland, isReactComponent } = await import(\n\t\t\t'./hydrators/react'\n\t\t);\n\t\tconst resolvedComponent =\n\t\t\t(await resolveComponent?.(framework, componentName)) ??\n\t\t\tgetIslandComponent(registry.react?.[componentName]);\n\t\tif (!isReactComponent(resolvedComponent)) return;\n\n\t\thydrateReactIsland(resolvedComponent, element, propsRecord);\n\t\telement.dataset.hydrated = 'true';\n\n\t\treturn;\n\t}\n\n\tif (framework === 'svelte') {\n\t\tconst { hydrateSvelteIsland, isSvelteComponent } = await import(\n\t\t\t'./hydrators/svelte'\n\t\t);\n\t\tconst resolvedComponent =\n\t\t\t(await resolveComponent?.(framework, componentName)) ??\n\t\t\tgetIslandComponent(registry.svelte?.[componentName]);\n\t\tif (!isSvelteComponent(resolvedComponent)) return;\n\n\t\thydrateSvelteIsland(resolvedComponent, element, propsRecord);\n\t\telement.dataset.hydrated = 'true';\n\n\t\treturn;\n\t}\n\n\tif (framework === 'vue') {\n\t\tconst { hydrateVueIsland, isVueComponent } = await import(\n\t\t\t'./hydrators/vue'\n\t\t);\n\t\tconst resolvedComponent =\n\t\t\t(await resolveComponent?.(framework, componentName)) ??\n\t\t\tgetIslandComponent(registry.vue?.[componentName]);\n\t\tif (!isVueComponent(resolvedComponent)) return;\n\n\t\thydrateVueIsland(resolvedComponent, element, propsRecord);\n\t\telement.dataset.hydrated = 'true';\n\n\t\treturn;\n\t}\n\n\tif (framework === 'angular') {\n\t\tconst { mountAngularIsland, isAngularComponent } = await import(\n\t\t\t'../angular/islands'\n\t\t);\n\t\tconst resolvedComponent =\n\t\t\t(await resolveComponent?.(framework, componentName)) ??\n\t\t\tgetIslandComponent(registry.angular?.[componentName]);\n\t\tconst { islandId } = element.dataset;\n\t\tif (!isAngularComponent(resolvedComponent) || !islandId) return;\n\n\t\tawait mountAngularIsland(\n\t\t\tresolvedComponent,\n\t\t\telement,\n\t\t\tpropsRecord ?? {},\n\t\t\tislandId\n\t\t);\n\t\telement.dataset.hydrated = 'true';\n\t}\n};\n\nconst hydrateIsland = async (\n\tregistry: RuntimeIslandRegistry,\n\telement: IslandElement,\n\tresolveComponent?: (\n\t\tframework: IslandFramework,\n\t\tcomponent: string\n\t) => Promise<unknown>\n) => {\n\tif (element.dataset.hydrated === 'true' || hydratingIslands.has(element)) {\n\t\treturn;\n\t}\n\n\tconst { framework } = element.dataset;\n\tconst componentName = element.dataset.component;\n\tif (!framework || !componentName) return;\n\n\tconst props = parseIslandProps(element.getAttribute('data-props'));\n\thydratingIslands.add(element);\n\n\ttry {\n\t\tawait hydrateByFramework(\n\t\t\tregistry,\n\t\t\tframework,\n\t\t\tcomponentName,\n\t\t\telement,\n\t\t\tprops,\n\t\t\tresolveComponent\n\t\t);\n\t} catch (error) {\n\t\tconst message =\n\t\t\terror instanceof Error ? error.message : 'Unknown island error';\n\t\telement.dataset.error = message;\n\t\tconsole.error(\n\t\t\t`[islands] Failed to hydrate ${framework}:${componentName}`,\n\t\t\terror\n\t\t);\n\t} finally {\n\t\thydratingIslands.delete(element);\n\t}\n};\n\nconst scheduleIsland = (\n\tregistry: RuntimeIslandRegistry,\n\telement: IslandElement,\n\tobserver: IntersectionObserver | null,\n\tresolveComponent?: (\n\t\tframework: IslandFramework,\n\t\tcomponent: string\n\t) => Promise<unknown>\n) => {\n\tconst mode = element.dataset.hydrate ?? 'load';\n\tif (mode === 'none') return;\n\tif (mode === 'load') {\n\t\tvoid hydrateIsland(registry, element, resolveComponent);\n\n\t\treturn;\n\t}\n\tif (mode === 'idle') {\n\t\trequestIdle(\n\t\t\t() => void hydrateIsland(registry, element, resolveComponent)\n\t\t);\n\n\t\treturn;\n\t}\n\tif (mode === 'visible' && observer) {\n\t\tobserver.observe(element);\n\n\t\treturn;\n\t}\n\n\tvoid hydrateIsland(registry, element, resolveComponent);\n};\n\nconst collectIslandElements = (node: Node) => {\n\tconst islands: IslandElement[] = [];\n\tif (isIslandElement(node)) islands.push(node);\n\tif (!(node instanceof Element)) return islands;\n\n\tconst nested = node.querySelectorAll<IslandElement>('[data-island=\"true\"]');\n\tfor (const island of nested) {\n\t\tislands.push(island);\n\t}\n\n\treturn islands;\n};\n\nexport const startIslands = ({\n\tregistry,\n\tresolveComponent,\n\troot = document.documentElement\n}: StartIslandsOptions) => {\n\tconst targetRoot = root instanceof Document ? root.documentElement : root;\n\n\tconst observer =\n\t\ttypeof IntersectionObserver === 'undefined'\n\t\t\t? null\n\t\t\t: new IntersectionObserver((entries) => {\n\t\t\t\t\tfor (const entry of entries) {\n\t\t\t\t\t\tif (!entry.isIntersecting) continue;\n\t\t\t\t\t\tif (!isIslandElement(entry.target)) continue;\n\n\t\t\t\t\t\tobserver?.unobserve(entry.target);\n\t\t\t\t\t\tvoid hydrateIsland(\n\t\t\t\t\t\t\tregistry,\n\t\t\t\t\t\t\tentry.target,\n\t\t\t\t\t\t\tresolveComponent\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t});\n\n\tconst islands = targetRoot.querySelectorAll<IslandElement>(\n\t\t'[data-island=\"true\"]'\n\t);\n\tfor (const island of islands) {\n\t\tscheduleIsland(registry, island, observer, resolveComponent);\n\t}\n\n\tif (typeof MutationObserver === 'undefined') return;\n\tif (observedRoots.has(targetRoot)) return;\n\n\tconst mutationObserver = new MutationObserver((records) => {\n\t\tconst addedIslands = records.flatMap((record) =>\n\t\t\tArray.from(record.addedNodes).flatMap(collectIslandElements)\n\t\t);\n\t\tfor (const island of addedIslands) {\n\t\t\tscheduleIsland(registry, island, observer, resolveComponent);\n\t\t}\n\t});\n\n\tobservedRoots.add(targetRoot);\n\tmutationObserver.observe(targetRoot, {\n\t\tchildList: true,\n\t\tsubtree: true\n\t});\n};\n",
|
|
26
26
|
"import type { RuntimeIslandRenderProps } from '../../types/island';\nimport { getIslandMarkerAttributes } from '../core/islandMarkupAttributes';\n\ntype PreservedIslandMarkup = {\n\tattributes: Record<string, string>;\n\tinnerHTML: string;\n};\n\ntype IslandMarkerElement = HTMLElement & {\n\tdataset: DOMStringMap & {\n\t\tcomponent?: string;\n\t\tframework?: string;\n\t\thydrate?: string;\n\t\tisland?: string;\n\t\tislandId?: string;\n\t\tprops?: string;\n\t};\n};\n\nconst getSnapshotMap = () => {\n\tif (typeof window === 'undefined') {\n\t\treturn null;\n\t}\n\n\twindow.__ABS_SERVER_ISLAND_HTML__ ??= new Map<\n\t\tstring,\n\t\tPreservedIslandMarkup[]\n\t>();\n\n\treturn window.__ABS_SERVER_ISLAND_HTML__;\n};\n\nconst getIslandSignature = (props: RuntimeIslandRenderProps) => {\n\tconst attributes = getIslandMarkerAttributes(props);\n\n\treturn [\n\t\tattributes['data-component'],\n\t\tattributes['data-framework'],\n\t\tattributes['data-hydrate'],\n\t\tattributes['data-props']\n\t].join('::');\n};\n\nconst isMatchingIslandElement = (\n\telement: Element,\n\tprops: RuntimeIslandRenderProps\n): element is IslandMarkerElement => {\n\tif (!(element instanceof HTMLElement)) {\n\t\treturn false;\n\t}\n\n\tconst attributes = getIslandMarkerAttributes(props);\n\n\treturn (\n\t\telement.dataset.island === 'true' &&\n\t\telement.dataset.component === attributes['data-component'] &&\n\t\telement.dataset.framework === attributes['data-framework'] &&\n\t\t(element.dataset.hydrate ?? 'load') === attributes['data-hydrate'] &&\n\t\t(element.dataset.props ?? '{}') === attributes['data-props']\n\t);\n};\n\nconst snapshotIslandElement = (\n\telement: HTMLElement,\n\tsnapshotMap: Map<string, PreservedIslandMarkup[]>\n) => {\n\tconst signature = [\n\t\telement.dataset.component,\n\t\telement.dataset.framework,\n\t\telement.dataset.hydrate ?? 'load',\n\t\telement.dataset.props ?? '{}'\n\t].join('::');\n\tconst existing = snapshotMap.get(signature) ?? [];\n\tconst attributes = Object.fromEntries(\n\t\telement\n\t\t\t.getAttributeNames()\n\t\t\t.map((name) => [name, element.getAttribute(name) ?? ''])\n\t);\n\texisting.push({\n\t\tattributes,\n\t\tinnerHTML: element.innerHTML\n\t});\n\tsnapshotMap.set(signature, existing);\n};\n\nexport const initializeIslandMarkupSnapshot = () => {\n\tif (typeof document === 'undefined') {\n\t\treturn;\n\t}\n\n\tconst snapshotMap = getSnapshotMap();\n\tif (!snapshotMap || snapshotMap.size > 0) {\n\t\treturn;\n\t}\n\n\tconst elements = Array.from(\n\t\tdocument.querySelectorAll<HTMLElement>('[data-island=\"true\"]')\n\t);\n\tfor (const element of elements) {\n\t\tsnapshotIslandElement(element, snapshotMap);\n\t}\n};\n\nexport const preserveIslandMarkup = (props: RuntimeIslandRenderProps) => {\n\tif (typeof document === 'undefined') {\n\t\treturn {\n\t\t\tattributes: getIslandMarkerAttributes(props),\n\t\t\tinnerHTML: ''\n\t\t};\n\t}\n\n\tconst snapshotMap = getSnapshotMap();\n\tconst signature = getIslandSignature(props);\n\t// Islands that share a signature (same component, framework, hydrate mode\n\t// and serialized props) produce byte-identical SSR markup, so the first\n\t// captured snapshot is correct for every instance. Returning it\n\t// unconditionally keeps this stateless: React may call the component many\n\t// times during a single hydration (StrictMode double-render, hydration\n\t// retries, mismatch regeneration), and a per-call claim counter would run\n\t// past the snapshot list and yield empty markup — making the host render\n\t// `dangerouslySetInnerHTML={{ __html: '' }}` and wipe the island's\n\t// server-rendered DOM before the island runtime can hydrate it.\n\tconst snapshotCandidate = snapshotMap?.get(signature)?.[0];\n\tif (snapshotCandidate) {\n\t\treturn snapshotCandidate;\n\t}\n\n\t// Snapshot not captured yet (the island runtime module hasn't evaluated):\n\t// fall back to reading the live SSR DOM directly.\n\tconst liveCandidate = Array.from(\n\t\tdocument.querySelectorAll('[data-island=\"true\"]')\n\t).find((element) => isMatchingIslandElement(element, props));\n\tif (!liveCandidate) {\n\t\treturn {\n\t\t\tattributes: getIslandMarkerAttributes(props),\n\t\t\tinnerHTML: ''\n\t\t};\n\t}\n\n\treturn {\n\t\tattributes: Object.fromEntries(\n\t\t\tliveCandidate\n\t\t\t\t.getAttributeNames()\n\t\t\t\t.map((name) => [name, liveCandidate.getAttribute(name) ?? ''])\n\t\t),\n\t\tinnerHTML: liveCandidate.innerHTML\n\t};\n};\n"
|
|
27
27
|
],
|
|
@@ -108,7 +108,7 @@ const buildLocationSection = (
|
|
|
108
108
|
|
|
109
109
|
if (lineText) {
|
|
110
110
|
const codeBlock = document.createElement('pre');
|
|
111
|
-
codeBlock.style.cssText = `${codeBlockStyle
|
|
111
|
+
codeBlock.style.cssText = `${codeBlockStyle}margin-top:8px;`;
|
|
112
112
|
codeBlock.textContent = lineText;
|
|
113
113
|
locSection.appendChild(codeBlock);
|
|
114
114
|
}
|
|
@@ -141,7 +141,7 @@ const buildStackSection = (stack: string | undefined, message: string) => {
|
|
|
141
141
|
label.textContent = 'Stack';
|
|
142
142
|
section.appendChild(label);
|
|
143
143
|
const pre = document.createElement('pre');
|
|
144
|
-
pre.style.cssText = `${codeBlockStyle
|
|
144
|
+
pre.style.cssText = `${codeBlockStyle}max-height:300px;overflow-y:auto;`;
|
|
145
145
|
pre.textContent = cleaned;
|
|
146
146
|
section.appendChild(pre);
|
|
147
147
|
|
|
@@ -155,7 +155,7 @@ const collectLoadedScripts = () => {
|
|
|
155
155
|
const scripts = Array.from(document.querySelectorAll('script[src]'));
|
|
156
156
|
const urls: string[] = [];
|
|
157
157
|
for (const script of scripts) {
|
|
158
|
-
const {src} =
|
|
158
|
+
const { src } = script as HTMLScriptElement;
|
|
159
159
|
if (!src) continue;
|
|
160
160
|
// Filter to JS we serve — vendor chunks, generated indexes, root
|
|
161
161
|
// chunk-XXX.js outputs. Skip user-pasted CDN scripts and the like.
|
|
@@ -195,7 +195,7 @@ const buildDiagnosticsSection = () => {
|
|
|
195
195
|
}
|
|
196
196
|
|
|
197
197
|
const pre = document.createElement('pre');
|
|
198
|
-
pre.style.cssText = `${codeBlockStyle
|
|
198
|
+
pre.style.cssText = `${codeBlockStyle}max-height:200px;overflow-y:auto;`;
|
|
199
199
|
pre.textContent = lines.join('\n');
|
|
200
200
|
section.appendChild(pre);
|
|
201
201
|
|