@jskit-ai/agent-docs 0.1.280 → 0.1.281
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/guide/agent/app-extras/assistant-conversation.md +5 -1
- package/guide/agent/app-extras/realtime.md +20 -10
- package/guide/agent/app-setup/authentication.md +20 -1
- package/guide/agent/app-setup/database-layer.md +75 -31
- package/guide/agent/app-setup/existing-application-migration.md +7 -1
- package/guide/agent/app-setup/multi-homing.md +6 -2
- package/guide/agent/app-setup/upgrading-jskit.md +75 -0
- package/guide/agent/framework/client-features.md +35 -1
- package/guide/agent/framework/sanity-checks.md +4 -3
- package/guide/agent/framework/typed-features.md +79 -30
- package/package.json +1 -1
- package/patterns/feature-package/example/booking-engine/package.json +1 -1
- package/patterns/minimal-foundation/example/AGENTS.md +14 -7
- package/patterns/minimal-foundation/example/package.json +3 -3
- package/patterns/minimal-foundation/example/playwright.config.mjs +3 -33
- package/patterns/minimal-foundation/example/server.js +7 -1
- package/patterns/minimal-foundation/example/tests/e2e/startup.spec.ts +13 -0
- package/patterns/shell-foundation/example/AGENTS.md +14 -7
- package/patterns/shell-foundation/example/package.json +4 -4
- package/patterns/shell-foundation/example/packages/main/package.json +1 -1
- package/patterns/shell-foundation/example/playwright.config.mjs +3 -33
- package/patterns/shell-foundation/example/server.js +7 -1
- package/patterns/shell-foundation/example/tests/e2e/startup.spec.ts +13 -0
- package/reference/autogen/PATTERN_INDEX.md +37 -37
- package/reference/autogen/packages/architecture-inspector.md +1 -0
- package/reference/autogen/packages/assistant-runtime.md +1 -1
- package/reference/autogen/packages/auth-provider-local-core.md +2 -1
- package/reference/autogen/packages/connectors-catalog.md +8 -0
- package/reference/autogen/packages/database-runtime.md +33 -0
- package/reference/autogen/packages/kernel.md +27 -1
- package/reference/autogen/packages/oidc-issuer-core.md +0 -1
- package/reference/autogen/packages/realtime.md +8 -5
- package/reference/autogen/packages/shell-web.md +4 -3
- package/reference/autogen/packages/workspaces-core.md +1 -1
- package/reference/autogen/tooling/jskit-catalog.md +71 -1
- package/skills/jskit/SKILL.md +8 -6
- package/skills/jskit/references/client-features.md +35 -1
- package/skills/jskit/references/existing-application-migration.md +7 -1
- package/skills/jskit/references/heuristics/typed-features.md +2 -2
- package/skills/jskit/references/heuristics/ui-testing.md +21 -16
- package/skills/jskit/references/multi-homing.md +6 -2
- package/skills/jskit/references/pattern-index.md +37 -37
- package/skills/jskit/references/patterns/app/minimal-foundation/example/AGENTS.md +14 -7
- package/skills/jskit/references/patterns/app/minimal-foundation/example/package.json +3 -3
- package/skills/jskit/references/patterns/app/minimal-foundation/example/playwright.config.mjs +3 -33
- package/skills/jskit/references/patterns/app/minimal-foundation/example/server.js +7 -1
- package/skills/jskit/references/patterns/app/minimal-foundation/example/tests/e2e/startup.spec.ts +13 -0
- package/skills/jskit/references/patterns/app/shell-foundation/example/AGENTS.md +14 -7
- package/skills/jskit/references/patterns/app/shell-foundation/example/package.json +4 -4
- package/skills/jskit/references/patterns/app/shell-foundation/example/packages/main/package.json +1 -1
- package/skills/jskit/references/patterns/app/shell-foundation/example/playwright.config.mjs +3 -33
- package/skills/jskit/references/patterns/app/shell-foundation/example/server.js +7 -1
- package/skills/jskit/references/patterns/app/shell-foundation/example/tests/e2e/startup.spec.ts +13 -0
- package/skills/jskit/references/patterns/auth/accounts-hub/example/package.json +2 -2
- package/skills/jskit/references/patterns/auth/oidc-sign-in/example/package.json +2 -2
- package/skills/jskit/references/patterns/auth/supabase-auth/example/package.json +1 -1
- package/skills/jskit/references/patterns/connectors/calendar-cli/example/package.json +4 -4
- package/skills/jskit/references/patterns/crud/json-api-resource-package/example/packages/books/package.json +2 -2
- package/skills/jskit/references/patterns/database/mysql-application/PATTERN.md +34 -24
- package/skills/jskit/references/patterns/database/mysql-application/example/package.json +3 -2
- package/skills/jskit/references/patterns/database/mysql-application/example/tests/e2e/databases.js +25 -0
- package/skills/jskit/references/patterns/database/postgres-application/PATTERN.md +12 -0
- package/skills/jskit/references/patterns/database/postgres-application/example/package.json +3 -2
- package/skills/jskit/references/patterns/database/postgres-application/example/tests/e2e/databases.js +25 -0
- package/skills/jskit/references/patterns/realtime/realtime-application/example/package.json +2 -2
- package/skills/jskit/references/patterns/server/feature-package/example/booking-engine/package.json +1 -1
- package/skills/jskit/references/patterns/users/user-administration-server/example/packages/users/package.json +2 -2
- package/skills/jskit/references/patterns/users/user-administration-server/example/packages/users-workspace/package.json +3 -3
- package/skills/jskit/references/sanity-checks.md +4 -3
- package/skills/jskit/references/typed-features.md +79 -30
- package/skills/jskit/references/patterns/database/mysql-application/example/tests/browser/database.js +0 -68
|
@@ -34,7 +34,8 @@ Exports
|
|
|
34
34
|
- `PROVIDER_ID`
|
|
35
35
|
- `buildAuthPayload({ user, session, profileProjector, profileOptions = {} })`
|
|
36
36
|
- `buildAuthResult({ user, session, appProfile })`
|
|
37
|
-
- `
|
|
37
|
+
- `buildProfileChangePayload({ user, profileProjector })`
|
|
38
|
+
- `buildSessionAuthPayload({ appProfileProjection, devAuth, profileProjector, request, session, user, syncProfile = true, onlyWhenChanged = false })`
|
|
38
39
|
- `findExistingAppProfile(user, profileProjector)`
|
|
39
40
|
- `isAuthenticatingSession(session)`
|
|
40
41
|
Local functions
|
|
@@ -951,6 +951,14 @@ Exports
|
|
|
951
951
|
- `zohoOAuthMetadata(accounts)`
|
|
952
952
|
- `normalizeZohoTokenResponse(response, expectedApiOrigin)`
|
|
953
953
|
|
|
954
|
+
### `src/shared/ai-definition.js`
|
|
955
|
+
Exports
|
|
956
|
+
- `aiAccessLabels`
|
|
957
|
+
- `aiDefinition`
|
|
958
|
+
- `byAccessThenKey(a, b)`
|
|
959
|
+
- `catalogueProvider(provider, connection)`
|
|
960
|
+
- `configurableProviders`
|
|
961
|
+
|
|
954
962
|
### `src/shared/ai.js`
|
|
955
963
|
Exports
|
|
956
964
|
- `aiCatalogue`
|
|
@@ -16,6 +16,7 @@ Use this on demand; do not load the full index at startup.
|
|
|
16
16
|
|
|
17
17
|
### `src/server/database.js`
|
|
18
18
|
Exports
|
|
19
|
+
- `RUNTIME_QUERY_CHANNEL`
|
|
19
20
|
- `createDatabase({ driver, env })`
|
|
20
21
|
Local functions
|
|
21
22
|
- `resolveDriverDialectId(driver)`
|
|
@@ -55,6 +56,38 @@ Local functions
|
|
|
55
56
|
Exports
|
|
56
57
|
- `DatabaseProvider`
|
|
57
58
|
|
|
59
|
+
### `src/server/testDatabaseFile.js`
|
|
60
|
+
Exports
|
|
61
|
+
- None
|
|
62
|
+
Local functions
|
|
63
|
+
- `isRunning(pid)`
|
|
64
|
+
- `claimDatabase(directory, databases)`
|
|
65
|
+
|
|
66
|
+
### `src/server/testDatabases.js`
|
|
67
|
+
Exports
|
|
68
|
+
- `RUN_SETTINGS_FILE`
|
|
69
|
+
- `countQueries(knex, work)`
|
|
70
|
+
- `countRuntimeQueries(work)`
|
|
71
|
+
- `matchesSnapshot(knexConfig, database, snapshot)`
|
|
72
|
+
- `prepareTestDatabases({ knexConfig, environment, variable = "TEST_DB_NAME", count = 1, seed, schema = {}, appRoot = process.cwd() })`
|
|
73
|
+
- `requireDisposableDatabase(environment, variable, count = 1, { connected = "" } = {})`
|
|
74
|
+
- `restoreTestDatabase(knexConfig, database, snapshot)`
|
|
75
|
+
- `testDatabaseNames(name, count)`
|
|
76
|
+
- `testDatabaseRun({ knexConfig, environment, count, schema, appRoot = process.cwd() })`
|
|
77
|
+
- `testDatabaseSnapshotKey(knexConfig, { appRoot = process.cwd(), schemaFiles = [] } = {})`
|
|
78
|
+
- `type TestDatabaseSchema`
|
|
79
|
+
Local functions
|
|
80
|
+
- `folded(value)`
|
|
81
|
+
- `milliseconds(since)`
|
|
82
|
+
- `ledgerOf(knexConfig)`
|
|
83
|
+
- `connectedDatabaseName(environment)`
|
|
84
|
+
- `knexOn(knexConfig, database, connectionOptions = {})`
|
|
85
|
+
- `withKnex(knexConfig, database, use, connectionOptions)`
|
|
86
|
+
- `ledgerNames(knex, ledger, tables)`
|
|
87
|
+
- `dialectOf(knexConfig)`
|
|
88
|
+
- `refusedPrivilege(error)`
|
|
89
|
+
- `recordStatements(listen, work)`
|
|
90
|
+
|
|
58
91
|
### `src/server/types.js`
|
|
59
92
|
Exports
|
|
60
93
|
- `type RuntimeDatabase`
|
|
@@ -538,6 +538,8 @@ Local functions
|
|
|
538
538
|
- `isSurfaceRootRecord(record)`
|
|
539
539
|
- `hostsChildViews(record)`
|
|
540
540
|
- `hashScrollMargin(hash)`
|
|
541
|
+
- `isLazyRouteComponent(component)`
|
|
542
|
+
- `preloadOpeningRouteComponents(router, fallbackRoute)`
|
|
541
543
|
|
|
542
544
|
### `client/shellRouting.js`
|
|
543
545
|
Exports
|
|
@@ -604,8 +606,12 @@ Local functions
|
|
|
604
606
|
- `hasClientExport(packageJson)`
|
|
605
607
|
- `isPathInsideRoot(rootPath, candidatePath)`
|
|
606
608
|
- `splitSpecifierSuffix(source)`
|
|
609
|
+
- `exportFile(target)`
|
|
610
|
+
- `resolveClientBootImports(installedPackage, { packageMetadataUiRoutes, packageMetadataClientProviders })`
|
|
607
611
|
- `resolveClientModulesFromInstalledPackages(installedPackages = [])`
|
|
608
612
|
- `normalizeClientModulePackageMetadataEntries(value)`
|
|
613
|
+
- `normalizeBootProviders(bootImports)`
|
|
614
|
+
- `clientBootSpecifiers(entry)`
|
|
609
615
|
- `resolveClientRuntimeDedupeSpecifiers(userResolveConfig = {})`
|
|
610
616
|
|
|
611
617
|
### `client/vite/index.js`
|
|
@@ -798,6 +804,12 @@ Local functions
|
|
|
798
804
|
- `emptyInput()`
|
|
799
805
|
- `handlerAsGiven(handler)`
|
|
800
806
|
|
|
807
|
+
### `server/http/lib/deepFrozen.js`
|
|
808
|
+
Exports
|
|
809
|
+
- `isDeepFrozen(value)`
|
|
810
|
+
Local functions
|
|
811
|
+
- `isFrozenThroughout(node, checked)`
|
|
812
|
+
|
|
801
813
|
### `server/http/lib/errors.js`
|
|
802
814
|
Exports
|
|
803
815
|
- `HttpKernelError`
|
|
@@ -831,6 +843,10 @@ Exports
|
|
|
831
843
|
- `type ActionCatalogue`
|
|
832
844
|
- `type RuntimeFastify`
|
|
833
845
|
Local functions
|
|
846
|
+
- `sharedValidationSchema(schema)`
|
|
847
|
+
- `namesEveryType(value)`
|
|
848
|
+
- `isSharedResponseSchema(entry)`
|
|
849
|
+
- `copyRouteSchema(schema)`
|
|
834
850
|
- `toFastifyRouteOptions(route)`
|
|
835
851
|
- `shouldStripFastifyBodySchema(route, schema)`
|
|
836
852
|
- `normalizeHeaderValue(value)`
|
|
@@ -860,6 +876,7 @@ Exports
|
|
|
860
876
|
- `resolveRouteValidatorOptions({ method = "", path = "", options = {} } = {})`
|
|
861
877
|
Local functions
|
|
862
878
|
- `stripJsonRestTransportExtensions(value)`
|
|
879
|
+
- `stripSchemaCopy(value)`
|
|
863
880
|
- `normalizeRouteSchemaSection(value, { context = "route section", defaultMode = "patch" } = {})`
|
|
864
881
|
- `normalizeResponseDefinition(value, { context = "route responses" } = {})`
|
|
865
882
|
- `normalizeAdvancedFastifySchema(value, { context = "route validator" } = {})`
|
|
@@ -869,9 +886,14 @@ Local functions
|
|
|
869
886
|
### `server/http/responseSerializerFactory.js`
|
|
870
887
|
Exports
|
|
871
888
|
- `createCachedResponseSerializerFactory(buildSerializer)`
|
|
889
|
+
- `schemaCacheKey(schema)`
|
|
872
890
|
Local functions
|
|
891
|
+
- `schemaTools()`
|
|
873
892
|
- `isJsonValue(value, ancestors = new Set())`
|
|
874
|
-
- `
|
|
893
|
+
- `assertValidSchema(schema, name)`
|
|
894
|
+
- `filedSchemaId(schema, fallback)`
|
|
895
|
+
- `everyRefResolves(schema, externalSchemas)`
|
|
896
|
+
- `compiledOnFirstUse(compile, options, key)`
|
|
875
897
|
|
|
876
898
|
### `server/http/securityHeaders.js`
|
|
877
899
|
Exports
|
|
@@ -1055,6 +1077,7 @@ Exports
|
|
|
1055
1077
|
Local functions
|
|
1056
1078
|
- `fileLockError(message = "", code = FILE_LOCK_ERROR_CODE)`
|
|
1057
1079
|
- `normalizedAbsolutePath(value = "", label = "path", errorCode = FILE_LOCK_ERROR_CODE)`
|
|
1080
|
+
- `lockThroughDescriptor(fd, cwd)`
|
|
1058
1081
|
|
|
1059
1082
|
### `server/support/importFreshModuleFromAbsolutePath.js`
|
|
1060
1083
|
Exports
|
|
@@ -1146,3 +1169,6 @@ Local functions
|
|
|
1146
1169
|
- `resolveFileDependencyRoot(appRoot, specifier = "")`
|
|
1147
1170
|
- `resolveInstalledPackageRoot({ appRoot, packageId, parentPackageRoot = "" })`
|
|
1148
1171
|
- `resolvePackageRoots({ appRoot, packageId, directSpecifier = "", parentPackageRoot = "" })`
|
|
1172
|
+
- `fileStamp(filePath)`
|
|
1173
|
+
- `stampsOf(filePaths)`
|
|
1174
|
+
- `walkInstalledPackages(normalizedAppRoot)`
|
|
@@ -76,6 +76,7 @@ Exports
|
|
|
76
76
|
- `type RuntimeDatabase`
|
|
77
77
|
- `type RuntimeLogger`
|
|
78
78
|
- `type ActorRoomsResolver`
|
|
79
|
+
- `type ActorsRoomsResolver`
|
|
79
80
|
- `type AudienceContributors`
|
|
80
81
|
Local functions
|
|
81
82
|
- `flattenEntries(value)`
|
|
@@ -107,16 +108,17 @@ Exports
|
|
|
107
108
|
|
|
108
109
|
### `src/server/realtimeDelivery.js`
|
|
109
110
|
Exports
|
|
110
|
-
- `createRealtimeDelivery({ io, database, logger, authService, audiences: { mayContribute,
|
|
111
|
+
- `createRealtimeDelivery({ io, database, logger, authService, audiences: { mayContribute, resolveActorsRooms } })`
|
|
111
112
|
- `matchesRealtimeEvent(event)`
|
|
112
113
|
- `type AuthService`
|
|
113
114
|
- `type ActorRoomsResolver`
|
|
115
|
+
- `type ActorsRoomsResolver`
|
|
114
116
|
- `type AudienceContributors`
|
|
115
117
|
Local functions
|
|
116
118
|
- `publicRealtimePayload(event)`
|
|
117
|
-
- `
|
|
118
|
-
- `
|
|
119
|
-
- `
|
|
119
|
+
- `sharedWithinPass(load, keyOf)`
|
|
120
|
+
- `createPassChecks(authService, resolveActorsRooms)`
|
|
121
|
+
- `rememberedActorId(socket)`
|
|
120
122
|
|
|
121
123
|
### `src/server/RealtimeProvider.js`
|
|
122
124
|
Exports
|
|
@@ -133,7 +135,7 @@ Exports
|
|
|
133
135
|
- `REDIS_NAMESPACE_ENV_KEY`
|
|
134
136
|
- `resolveRealtimeRedisUrl(env)`
|
|
135
137
|
- `resolveRealtimeRedisNamespace(env)`
|
|
136
|
-
- `configureSocketIoRedisAdapter(io, { redisUrl = "", redisNamespace = "", logger, createRedisAdapter
|
|
138
|
+
- `configureSocketIoRedisAdapter(io, { redisUrl = "", redisNamespace = "", logger, createRedisAdapter, createRedisConnection })`
|
|
137
139
|
- `closeSocketIoRedisConnections({ pubClient, subClient })`
|
|
138
140
|
- `countConnectedClients(io)`
|
|
139
141
|
Local functions
|
|
@@ -149,6 +151,7 @@ Exports
|
|
|
149
151
|
Exports
|
|
150
152
|
- `type RuntimeRealtime`
|
|
151
153
|
- `type ActorRoomsResolver`
|
|
154
|
+
- `type ActorsRoomsResolver`
|
|
152
155
|
- `type AudienceContributors`
|
|
153
156
|
- `type RealtimeAudienceContributor`
|
|
154
157
|
|
|
@@ -500,10 +500,11 @@ Exports
|
|
|
500
500
|
- `resolveAppPlacementTopologyExport(exported, logger)`
|
|
501
501
|
Local functions
|
|
502
502
|
- `loadAppModule({ importModule, specifier, label, resolve, invalidExportMessage = "", loadFailureMessage, fallback, logger, asyncModuleRecoveryRuntime })`
|
|
503
|
-
- `
|
|
504
|
-
- `
|
|
503
|
+
- `importAppModules()`
|
|
504
|
+
- `loadAppPlacementDefinitions(logger, asyncModuleRecoveryRuntime, pendingImport)`
|
|
505
|
+
- `loadAppPlacementTopology(logger, asyncModuleRecoveryRuntime, pendingImport)`
|
|
505
506
|
- `createErrorConfigToolkit(errorRuntime)`
|
|
506
|
-
- `loadAppErrorConfig(logger, errorRuntime, asyncModuleRecoveryRuntime)`
|
|
507
|
+
- `loadAppErrorConfig(logger, errorRuntime, asyncModuleRecoveryRuntime, pendingImport)`
|
|
507
508
|
- `installVueErrorBridge(vueApp, errorRuntime, logger)`
|
|
508
509
|
- `installRouterErrorBridge(router, errorRuntime, logger)`
|
|
509
510
|
|
|
@@ -252,7 +252,7 @@ Exports
|
|
|
252
252
|
Exports
|
|
253
253
|
- `WorkspacesIntegrationsProvider`
|
|
254
254
|
Local functions
|
|
255
|
-
- `resolveWorkspaceRealtimeScopes(workspaceMemberships,
|
|
255
|
+
- `resolveWorkspaceRealtimeScopes(workspaceMemberships, actorIds)`
|
|
256
256
|
|
|
257
257
|
### `src/server/workspacesRuntime.js`
|
|
258
258
|
Exports
|
|
@@ -14,6 +14,45 @@ Use this on demand; do not load the full index at startup.
|
|
|
14
14
|
|
|
15
15
|
### scripts
|
|
16
16
|
|
|
17
|
+
### `scripts/browser-test-build.mjs`
|
|
18
|
+
Exports
|
|
19
|
+
- `buildFrontend({ appRoot = process.cwd(), build = "npm run build", run = runToCompletion } = {})`
|
|
20
|
+
Local functions
|
|
21
|
+
- `seconds(since)`
|
|
22
|
+
- `digest(file)`
|
|
23
|
+
- `buildFingerprint(appRoot, build, env = process.env)`
|
|
24
|
+
- `runToCompletion(command, appRoot)`
|
|
25
|
+
- `lastBuild(appRoot)`
|
|
26
|
+
- `isRunning(pid)`
|
|
27
|
+
- `lockBuild(appRoot)`
|
|
28
|
+
- `isCurrent(appRoot, inputs)`
|
|
29
|
+
|
|
30
|
+
### `scripts/browser-test-servers.mjs`
|
|
31
|
+
Exports
|
|
32
|
+
- None
|
|
33
|
+
Local functions
|
|
34
|
+
- `seconds(since)`
|
|
35
|
+
- `words(command)`
|
|
36
|
+
- `prepareWorkers(appRoot, prepare, workers, baseUrls)`
|
|
37
|
+
- `signInWorkers(appRoot, signIn, baseUrls, environments, signedInStates)`
|
|
38
|
+
- `waitUntilReady(url, server, name)`
|
|
39
|
+
- `stopServers()`
|
|
40
|
+
|
|
41
|
+
### `scripts/browser-test-times.mjs`
|
|
42
|
+
Exports
|
|
43
|
+
- None
|
|
44
|
+
|
|
45
|
+
### `scripts/browser-tests.mjs`
|
|
46
|
+
Exports
|
|
47
|
+
- `SETTINGS_VARIABLE`
|
|
48
|
+
- `browserTestConfig({ testDir = "./tests/e2e", port = DEFAULT_PORT, server = "node ./bin/server.js", build = "npm run build", prepare = "", signIn = "", env = {}, health = "/api/health", globalTimeout = GLOBAL_TIMEOUT_MS, environment = process.env, cwd = process.cwd() } = {})`
|
|
49
|
+
- `browserTestWorkers({ env = process.env, argv = process.argv } = {})`
|
|
50
|
+
Local functions
|
|
51
|
+
- `positiveInteger(value)`
|
|
52
|
+
- `managedBaseUrl(env)`
|
|
53
|
+
- `commandLineWorkers(argv)`
|
|
54
|
+
- `preparedWorkerEnvironment(file, index)`
|
|
55
|
+
|
|
17
56
|
### `scripts/build-catalog.mjs`
|
|
18
57
|
Exports
|
|
19
58
|
- None
|
|
@@ -245,10 +284,26 @@ Exports
|
|
|
245
284
|
Exports
|
|
246
285
|
- `planTestRuns(args, { cwd = process.cwd(), concurrency = testConcurrency() } = {})`
|
|
247
286
|
- `runTests(args)`
|
|
287
|
+
- `withTimeReporter(run, destination)`
|
|
248
288
|
Local functions
|
|
249
289
|
- `findTestFiles(patterns, cwd)`
|
|
250
290
|
- `readAloneFiles(files, cwd)`
|
|
251
|
-
- `
|
|
291
|
+
- `aloneDestination(destination)`
|
|
292
|
+
- `aloneRunOptions(options)`
|
|
293
|
+
- `aloneShard(files, options)`
|
|
294
|
+
- `runNode(args, env)`
|
|
295
|
+
|
|
296
|
+
### `scripts/test-databases.mjs`
|
|
297
|
+
Exports
|
|
298
|
+
- `DATABASES_OPTION`
|
|
299
|
+
- `testDatabaseRunFor(count, cwd = process.cwd())`
|
|
300
|
+
Local functions
|
|
301
|
+
- `withOwnEnvironment(load)`
|
|
302
|
+
|
|
303
|
+
### `scripts/test-file-stop.mjs`
|
|
304
|
+
Exports
|
|
305
|
+
- `STOPPED_PREFIX`
|
|
306
|
+
- `STOPS_VARIABLE`
|
|
252
307
|
|
|
253
308
|
### `scripts/test-runs.mjs`
|
|
254
309
|
Exports
|
|
@@ -262,8 +317,23 @@ Local functions
|
|
|
262
317
|
- `configOption(args)`
|
|
263
318
|
- `lineOf(contents, needle, after = "")`
|
|
264
319
|
- `findConfig(directory, explicit, names)`
|
|
320
|
+
- `usesBrowserHarness(source)`
|
|
321
|
+
- `developmentServerCommand(source)`
|
|
322
|
+
- `checkPlaywrightIsolation({ file, source, report })`
|
|
265
323
|
- `checkRunnerConfig({ root, configPath, directory, runner, report })`
|
|
266
324
|
|
|
325
|
+
### `scripts/test-time-report.mjs`
|
|
326
|
+
Exports
|
|
327
|
+
- `BOUNDS_FILE`
|
|
328
|
+
- `FILE_TIMES`
|
|
329
|
+
- `checkTestTimes({ bounds, files, tests, wallMs, stopped = [] })`
|
|
330
|
+
- `fileStop({ bound, recorded })`
|
|
331
|
+
- `reportTestTimes({ cwd, collected, directory, wallMs })`
|
|
332
|
+
- `writeFileStops({ cwd, files, directory })`
|
|
333
|
+
Local functions
|
|
334
|
+
- `seconds(ms)`
|
|
335
|
+
- `readTestTimeBounds(cwd)`
|
|
336
|
+
|
|
267
337
|
### `scripts/verify-packages.mjs`
|
|
268
338
|
Exports
|
|
269
339
|
- `main()`
|
package/skills/jskit/SKILL.md
CHANGED
|
@@ -131,9 +131,11 @@ slowest files. Find why a check is slow; never raise its time limit. Typed
|
|
|
131
131
|
features' repository and Tests rules say how.
|
|
132
132
|
|
|
133
133
|
Test files run in parallel by default, bounded by the machine: a script runs
|
|
134
|
-
`jskit test
|
|
135
|
-
|
|
136
|
-
`@jskit-ai/jskit-catalog/
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
134
|
+
`jskit test` (`--databases`: a `TEST_DB_NAME` copy per file), never
|
|
135
|
+
`node --test` or a fixed `--test-concurrency`; Playwright's config is
|
|
136
|
+
`browserTestConfig()` from `@jskit-ai/jskit-catalog/browser-tests` and Vitest's
|
|
137
|
+
`maxWorkers` is `testConcurrency()` from `@jskit-ai/jskit-catalog/test-budget`.
|
|
138
|
+
Plain `jskit check` fails anything else. Files that collide when run together
|
|
139
|
+
get isolated (their own port, temporary directory and database), never
|
|
140
|
+
serialised. A file that truly must run alone says why on its first line,
|
|
141
|
+
`// jskit-test: alone - <reason>`.
|
|
@@ -232,7 +232,7 @@ const ConversationClientProvider = defineProvider({
|
|
|
232
232
|
},
|
|
233
233
|
/** @param {{ components: import("@jskit-ai/kernel/client/types").ClientComponents }} capabilities */
|
|
234
234
|
setup({ components }) {
|
|
235
|
-
components.register("conversation.web.
|
|
235
|
+
components.register("conversation.web.status.widget", ConversationStatusWidget);
|
|
236
236
|
}
|
|
237
237
|
});
|
|
238
238
|
|
|
@@ -241,6 +241,40 @@ const components = new Map();
|
|
|
241
241
|
export function registerComponent(id, component) { components.set(id, component); }
|
|
242
242
|
```
|
|
243
243
|
|
|
244
|
+
### Provider subpaths
|
|
245
|
+
|
|
246
|
+
**Export each client provider by a subpath of its own. The provider's file
|
|
247
|
+
imports only what every page needs, such as a widget the shell always shows; a
|
|
248
|
+
screen that only some routes show is imported by those routes.**
|
|
249
|
+
|
|
250
|
+
Why: every page of every app loads the client providers, and what they import,
|
|
251
|
+
before it shows anything. The client bootstrap imports a provider through the
|
|
252
|
+
subpath export that names its file, so the screens `./client` re-exports, and
|
|
253
|
+
their libraries, load only with the routes that show them. A provider without a
|
|
254
|
+
subpath, or a `./client` that declares `routeComponents` or `clientRoutes` or
|
|
255
|
+
uses `export *`, brings all of `./client` to every page.
|
|
256
|
+
|
|
257
|
+
```json
|
|
258
|
+
// good: package.json
|
|
259
|
+
"exports": {
|
|
260
|
+
"./client": "./src/client/index.js",
|
|
261
|
+
"./client/providers/ConversationClientProvider": "./src/client/providers/ConversationClientProvider.js"
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
// bad: package.json, no subpath for the provider, so every page loads all of ./client
|
|
265
|
+
"exports": {
|
|
266
|
+
"./client": "./src/client/index.js"
|
|
267
|
+
}
|
|
268
|
+
```
|
|
269
|
+
|
|
270
|
+
```js
|
|
271
|
+
// good: the provider's file imports the widget every page shows
|
|
272
|
+
import ConversationStatusWidget from "../components/ConversationStatusWidget.vue";
|
|
273
|
+
|
|
274
|
+
// bad: the provider's file imports a screen that only its route shows
|
|
275
|
+
import ConversationSettingsScreen from "../components/ConversationSettingsScreen.vue";
|
|
276
|
+
```
|
|
277
|
+
|
|
244
278
|
### Injected values
|
|
245
279
|
|
|
246
280
|
**`inject()` takes the owner's exported key, never a literal. A required value
|
|
@@ -128,7 +128,13 @@ The foundation servers reuse compiled response serializers for identical JSON
|
|
|
128
128
|
schemas through `createCachedResponseSerializerFactory` from
|
|
129
129
|
`@jskit-ai/kernel/server/http`. This reduces duplicate startup compilation and
|
|
130
130
|
retained memory in applications with many routes. Each Fastify compiler context
|
|
131
|
-
keeps its own cache; request data and response payloads are not cached.
|
|
131
|
+
keeps its own cache; request data and response payloads are not cached. A
|
|
132
|
+
serializer is compiled when a response first uses it, in every environment, so
|
|
133
|
+
startup compiles none. Startup still checks every response schema as
|
|
134
|
+
fast-json-stringify would before building it: an invalid schema or a `$ref`
|
|
135
|
+
that does not resolve stops the server. A problem fast-json-stringify only
|
|
136
|
+
finds while generating a serializer fails the first response that uses it, so
|
|
137
|
+
keep a test that calls each route.
|
|
132
138
|
|
|
133
139
|
Existing applications adopt the same setup in their own `server.js` after
|
|
134
140
|
upgrading JSKIT and declaring the directly used
|
|
@@ -85,9 +85,9 @@ ends with the same link.
|
|
|
85
85
|
- [Tests are not callers](../typed-features.md#tests-are-not-callers)
|
|
86
86
|
- `…ForTests`, `__reset…`, `testOnly…` exports (`jskit/no-test-only-export`)
|
|
87
87
|
- [No test-only exports](../typed-features.md#no-test-only-exports)
|
|
88
|
-
- a list, batch or write test with one to three rows, no query count, a fixed query ceiling tuned to pass, a slow endpoint first seen with real data
|
|
88
|
+
- a list, batch or write test with one to three rows, no query count, a fixed query ceiling tuned to pass, a slow endpoint first seen with real data, a hand-written `knex.on("query")` counter, a patched `Client.prototype.query`, `countQueries`, `countRuntimeQueries`, a route's query count
|
|
89
89
|
- [Query counts at realistic sizes](../typed-features.md#query-counts-at-realistic-sizes)
|
|
90
|
-
- `node --test --test-concurrency=1`, `workers: 1`, `fileParallelism: false`, a suite that runs one file at a time, test files that collide when run together, `test/*` findings of `jskit check`
|
|
90
|
+
- `node --test --test-concurrency=1`, `workers: 1`, `fileParallelism: false`, a suite that runs one file at a time, test files that collide when run together, a Playwright webServer running `npm run develop` or `vite`, a browser suite that takes hours, `test/*` findings of `jskit check`
|
|
91
91
|
- [Test files run in parallel](../typed-features.md#test-files-run-in-parallel)
|
|
92
92
|
- `knex.migrate.latest()` in each test file, a template database rebuilt by migrating, test preparation slower than its tests
|
|
93
93
|
- [Test databases are prepared once](../typed-features.md#test-databases-are-prepared-once)
|
|
@@ -50,23 +50,28 @@ Rules:
|
|
|
50
50
|
## Keep startup incremental
|
|
51
51
|
|
|
52
52
|
Run related cases in one suite invocation. Prepare the isolated database and
|
|
53
|
-
fixtures once for that invocation, never once per test.
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
53
|
+
fixtures once for that invocation, never once per test. An app's
|
|
54
|
+
`playwright.config.mjs` is `browserTestConfig()` from
|
|
55
|
+
`@jskit-ai/jskit-catalog/browser-tests`: the production build, made once and
|
|
56
|
+
reused while its sources are unchanged, and one server, port and database per
|
|
57
|
+
worker. Its `prepare` module (the `database/mysql-application` and
|
|
58
|
+
`database/postgres-application` patterns' `example/tests/e2e/databases.js`)
|
|
59
|
+
restores each worker's copy of `BROWSER_TEST_DB_NAME` from the stored schema
|
|
60
|
+
snapshot and runs the fixture seed, which restores any migration-owned
|
|
61
|
+
baseline rows. The migrations are replayed only when one changes, so a second
|
|
62
|
+
run reports a stored snapshot, no stale rows, and an unchanged normal
|
|
63
|
+
database.
|
|
64
|
+
|
|
65
|
+
Use `BROWSER_TEST_DB_NAME` for the browser copies and a different
|
|
66
|
+
`TEST_DB_NAME` for disposable integration and migration tests; the harness
|
|
67
|
+
refuses a collision, or one with the application's database, before
|
|
68
|
+
connecting.
|
|
69
|
+
|
|
70
|
+
Do not replay completed migrations, build every module fixture, or run a
|
|
71
|
+
production frontend build for each focused check. A
|
|
68
72
|
build made once for a whole run is different: it is the fix when a development
|
|
69
|
-
server makes every page load slow
|
|
73
|
+
server makes every page load slow, and browser tests never run on the
|
|
74
|
+
development server. Choose small fixture sets for the selected
|
|
70
75
|
suite; realistic row counts belong in the database tests that compare each
|
|
71
76
|
endpoint's query counts. Fresh-schema
|
|
72
77
|
migration tests and production-artifact tests are separate operations. Measure
|
|
@@ -56,8 +56,12 @@ config.tenancyPolicy = {
|
|
|
56
56
|
```
|
|
57
57
|
|
|
58
58
|
Provisioning runs in the users profile-sync lifecycle after registration and
|
|
59
|
-
sign-in
|
|
60
|
-
|
|
59
|
+
sign-in, at each session refresh, and on a request whose identity's email or
|
|
60
|
+
display name changed. The first run creates the personal workspace, its owner
|
|
61
|
+
membership and its settings; later runs reuse it. An ordinary request only reads
|
|
62
|
+
the existing profile, so a personal workspace, owner membership or settings row
|
|
63
|
+
deleted while the person is signed in comes back at their next sign-in or
|
|
64
|
+
session refresh, not at their next request. The default name is the user's display name,
|
|
61
65
|
or email, followed by "'s Workspace". To choose another, provide the
|
|
62
66
|
`workspaces.personal-workspace-name` capability from an application feature. It
|
|
63
67
|
receives the synchronized profile (`id`, `displayName`, `email`, `username`), and
|