Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
2 changes: 1 addition & 1 deletion packages/kbn-optimizer/limits.yml
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@ pageLoadAssetSize:
searchQueryRules: 6689
searchSynonyms: 6371
security: 79627
securitySolution: 160000
securitySolution: 172947
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This new limit far exceeds the current count as per the latest build, which is 153.5KB. Should we choose a more conservative value here, or perhaps even keep the current limit as the change doesn't seem needed?

securitySolutionEss: 38689
securitySolutionServerless: 52082
serverless: 7412
Expand Down
1 change: 1 addition & 0 deletions src/core/packages/root/server-internal/moon.yml
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ dependsOn:
- '@kbn/core-data-streams-server-internal'
- '@kbn/tracing-utils'
- '@kbn/core-user-activity-server-internal'
- '@kbn/zod'
tags:
- shared-server
- package
Expand Down
16 changes: 16 additions & 0 deletions src/core/packages/root/server-internal/src/server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ import { PricingService } from '@kbn/core-pricing-server-internal';
import { CoreInjectionService } from '@kbn/core-di-server-internal';
import { SpanStatusCode } from '@opentelemetry/api';
import { withActiveSpan } from '@kbn/tracing-utils';
import { setLazySchemaDisabled } from '@kbn/zod';
import { registerServiceConfig } from './register_service_config';
import { MIGRATION_EXCEPTION_CODE } from './constants';
import { coreConfig, type CoreConfigType } from './core_config';
Expand Down Expand Up @@ -218,6 +219,10 @@ export class Server {
const nodePreboot = await this.node.preboot({ loggingSystem: this.loggingSystem });
this.nodeRoles = nodePreboot.roles;

// Apply the `disableLazyZodSchemas` static override for `@kbn/zod` before plugin
// discovery so that `lazySchema` calls evaluated at plugin-module-load time observe it.
await this.#applyLazyZodSchemaOverride();

// Discover any plugins before continuing. This allows other systems to utilize the plugin dependency graph.
this.discoveredPlugins = await this.plugins.discover({
environment: environmentPreboot,
Expand Down Expand Up @@ -681,6 +686,17 @@ export class Server {
}
}

async #applyLazyZodSchemaOverride() {
const featureFlagsCfg = await firstValueFrom(
this.configService.atPath<{ overrides?: Record<string, unknown> }>('feature_flags')
);
const override = featureFlagsCfg.overrides?.disableLazyZodSchemas;

if (typeof override === 'boolean') {
setLazySchemaDisabled(override);
}
}

private registerCoreContext(coreSetup: InternalCoreSetup) {
coreSetup.http.registerRouteHandlerContext<RequestHandlerContext, 'core'>(
coreId,
Expand Down
1 change: 1 addition & 0 deletions src/core/packages/root/server-internal/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@
"@kbn/core-data-streams-server-internal",
"@kbn/tracing-utils",
"@kbn/core-user-activity-server-internal",
"@kbn/zod",
],
"exclude": [
"target/**/*",
Expand Down
39 changes: 38 additions & 1 deletion src/platform/packages/shared/kbn-lazy-object/README.md
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AI generated the detailed description. It looks useful so I'll keep it.

Original file line number Diff line number Diff line change
@@ -1,3 +1,40 @@
# @kbn/lazy-object

Empty package generated by @kbn/generate
Utilities for deferring the construction of objects until they are first used,
so that modules that declare many objects at load-time don't pay the
construction cost (time and memory) for the ones that are never touched.

The package offers several variants that differ in granularity, caching, and
how they're authored:

## `lazyObject(obj)` + Babel plugin

Author object literals normally; a Babel plugin rewrites `lazyObject({ ... })`
call sites into `createLazyObjectFromFactories({ key: () => expr, ... })` so
each property is built on first access and cached forever. At runtime without
the Babel plugin this is an identity function.

Use when: you want ergonomic lazy fields on an object without changing source
style. Requires the Babel plugin in the build.

## `createLazyObjectFromFactories(factories)`

Runtime-only version of the above. Takes an object whose values are factory
functions and returns an object whose properties materialize on first read
(cached forever). No build-time support needed.

Use when: you want per-property laziness without the Babel plugin.

## `createLazyObjectFromAnnotations(obj)` + `annotateLazy(fn)`

Like `createLazyObjectFromFactories`, but you mark individual factory values
with `annotateLazy(...)` so an object can mix eagerly-defined fields with
lazily-computed ones.

Use when: only some fields of an object benefit from laziness.

## Metrics

`getLazyObjectMetrics()` returns a `{ count, called }` snapshot for the
annotation-based variants (how many lazy keys were registered vs. materialized),
useful when evaluating whether laziness is paying off in a given module graph.
Original file line number Diff line number Diff line change
Expand Up @@ -16,17 +16,21 @@
* version: not applicable
*/

import { z } from '@kbn/zod/v4';
import { z, lazySchema } from '@kbn/zod/v4';

export const PlatformErrorResponse = lazySchema(() =>
z.object({
statusCode: z.number().int(),
error: z.string(),
message: z.string(),
})
);
export type PlatformErrorResponse = z.infer<typeof PlatformErrorResponse>;
export const PlatformErrorResponse = z.object({
statusCode: z.number().int(),
error: z.string(),
message: z.string(),
});

export const SiemErrorResponse = lazySchema(() =>
z.object({
status_code: z.number().int(),
message: z.string(),
})
);
export type SiemErrorResponse = z.infer<typeof SiemErrorResponse>;
export const SiemErrorResponse = z.object({
status_code: z.number().int(),
message: z.string(),
});
Original file line number Diff line number Diff line change
Expand Up @@ -16,17 +16,17 @@
* version: not applicable
*/

import { z } from '@kbn/zod/v4';
import { z, lazySchema } from '@kbn/zod/v4';
import { isNonEmptyString } from '@kbn/zod-helpers/v4';

/**
* A string that does not contain only whitespace characters
*/
export const NonEmptyString = lazySchema(() => z.string().min(1).superRefine(isNonEmptyString));
export type NonEmptyString = z.infer<typeof NonEmptyString>;
export const NonEmptyString = z.string().min(1).superRefine(isNonEmptyString);

/**
* A universally unique identifier
*/
export const UUID = lazySchema(() => z.string().uuid());
export type UUID = z.infer<typeof UUID>;
export const UUID = z.string().uuid();
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

{{> disclaimer}}

import { z } from '@kbn/zod/v4';
import { z, lazySchema } from '@kbn/zod/v4';
{{#if useZodHelpers}}
import { isValidDateMath, isNonEmptyString, ArrayFromString, BooleanFromString } from '@kbn/zod-helpers/v4';
{{/if}}
Expand All @@ -30,18 +30,18 @@ import {
{{#if (isCircularSchema @key)}}
export type {{transformSchemaName @key}} = {{> ts_type}};
export type {{transformSchemaName @key}}Input = {{> ts_input_type }};
export const {{transformSchemaName @key}}: z.ZodType<{{transformSchemaName @key}}, {{transformSchemaName @key}}Input> = {{> zod_schema_item }};
export const {{transformSchemaName @key}}: z.ZodType<{{transformSchemaName @key}}, {{transformSchemaName @key}}Input> = lazySchema(() => {{> zod_schema_item }} as z.ZodType<{{transformSchemaName @key}}, {{transformSchemaName @key}}Input>);
{{else}}
{{#if (shouldCastExplicitly this)}}
{{!-- We need this temporary type to infer from it below, but in the end we want to export as a casted {{transformSchemaName @key}} type --}}
{{!-- error TS7056: The inferred type of this node exceeds the maximum length the compiler will serialize. An explicit type annotation is needed. --}}
export const {{transformSchemaName @key}}Internal = {{> zod_schema_item}};
export const {{transformSchemaName @key}}Internal = lazySchema(() => {{> zod_schema_item}});

export type {{transformSchemaName @key}} = z.infer<typeof {{transformSchemaName @key}}Internal>;
export const {{transformSchemaName @key}} = {{transformSchemaName @key}}Internal as z.ZodType<{{transformSchemaName @key}}>;
{{else}}
export const {{transformSchemaName @key}} = lazySchema(() => {{> zod_schema_item}});
export type {{transformSchemaName @key}} = z.infer<typeof {{transformSchemaName @key}}>;
export const {{transformSchemaName @key}} = {{> zod_schema_item}};
{{/if }}
{{/if}}
{{#if enum}}
Expand All @@ -60,8 +60,8 @@ export const {{transformSchemaName @key}}Enum = {{transformSchemaName @key}}.enu
* {{{requestQuery.description}}}
*/
{{/if}}
export const {{operationId}}RequestQuery = lazySchema(() => {{> zod_query_item requestQuery }});
export type {{operationId}}RequestQuery = z.infer<typeof {{operationId}}RequestQuery>;
export const {{operationId}}RequestQuery = {{> zod_query_item requestQuery }};
export type {{operationId}}RequestQueryInput = z.input<typeof {{operationId}}RequestQuery>;
{{/if}}

Expand All @@ -71,8 +71,8 @@ export type {{operationId}}RequestQueryInput = z.input<typeof {{operationId}}Req
* {{{requestParams.description}}}
*/
{{/if}}
export const {{operationId}}RequestParams = lazySchema(() => {{> zod_schema_item requestParams }});
export type {{operationId}}RequestParams = z.infer<typeof {{operationId}}RequestParams>;
export const {{operationId}}RequestParams = {{> zod_schema_item requestParams }};
export type {{operationId}}RequestParamsInput = z.input<typeof {{operationId}}RequestParams>;
{{/if}}

Expand All @@ -82,8 +82,8 @@ export type {{operationId}}RequestParamsInput = z.input<typeof {{operationId}}Re
* {{{requestBody.description}}}
*/
{{/if}}
export const {{operationId}}RequestBody = lazySchema(() => {{> zod_schema_item requestBody }});
export type {{operationId}}RequestBody = z.infer<typeof {{operationId}}RequestBody>;
export const {{operationId}}RequestBody = {{> zod_schema_item requestBody }};
export type {{operationId}}RequestBodyInput = z.input<typeof {{operationId}}RequestBody>;
{{/if}}

Expand All @@ -93,7 +93,7 @@ export type {{operationId}}RequestBodyInput = z.input<typeof {{operationId}}Requ
* {{{response.description}}}
*/
{{/if}}
export const {{operationId}}Response = lazySchema(() => {{> zod_schema_item response }});
export type {{operationId}}Response = z.infer<typeof {{operationId}}Response>;
export const {{operationId}}Response = {{> zod_schema_item response }};
{{/if}}
{{/each}}
1 change: 1 addition & 0 deletions src/platform/packages/shared/kbn-zod/v4/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,4 @@

export * from 'zod/v4';
export { isZod } from './util';
export { lazySchema, setLazySchemaDisabled } from './lazy_schema';
Loading
Loading