Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
469de96
feat(router): add SetWildcardScope to bypass @requiresScopes checks
jensneuse Feb 18, 2026
9d375dc
fix(router): improve SetWildcardScope tests and doc comment
jensneuse Feb 18, 2026
1b39435
fix(router): address PR review feedback for SetWildcardScope
jensneuse Feb 26, 2026
6713fd2
chore: take care of comments
alepane21 May 11, 2026
4c02108
fix(router): clear slowplancache entries on Close to prevent memory l…
arutkowski00 Jun 24, 2026
ec5d35e
fix(router): config reload memory leak — graphMux nil + proto reset (#3)
arutkowski00 Jun 25, 2026
27e33a2
Merge branch 'wundergraph:main' into monday-tweaks
arutkowski00 Jun 25, 2026
d653d13
perf(router): size-aware execution-plan cache eviction (mondaytweaks …
arutkowski00 Jul 3, 2026
b887fd8
fix(router): join websocket connection handlers before executor.Close…
arutkowski00 Jul 3, 2026
498a51b
feat(router): expose subgraph fetch count context field (#6)
arutkowski00 Jul 3, 2026
52d6a24
Merge upstream/main into monday-tweaks
arutkowski00 Jul 6, 2026
4e5bf95
Merge remote-tracking branch 'upstream/main' into monday-tweaks
arutkowski00 Jul 6, 2026
980d896
Merge origin/monday-tweaks into monday-tweaks
arutkowski00 Jul 6, 2026
9455ffe
chore(router): remove mondaytweaks memory-leak flags after upstream #…
arutkowski00 Jul 7, 2026
98cdbf5
Merge upstream/main into monday-tweaks
arutkowski00 Jul 7, 2026
e747f79
test(router): refresh config goldens for DisableSizeAwarePlanCache field
arutkowski00 Jul 7, 2026
96a9474
patch https://monday.slack.com/archives/C09NXK51KR8/p1783523211012779…
budziam Jul 8, 2026
8c36f66
chore(router): disable websocket-disablement mondaytweaks flags (#11)
arutkowski00 Jul 8, 2026
0b3ca8a
fix(router): bound + detach old graph-server shutdown on config swap …
arutkowski00 Jul 9, 2026
3bb9b4a
Make mondaytweaks flags configurable in a runtime (#13)
budziam Jul 9, 2026
0094714
Merge branch 'wundergraph:main' into monday-tweaks
budziam Jul 10, 2026
81bdaa1
test(router): assert graph server drain only waits on muxes it tears …
endigma Jul 8, 2026
c7f0360
fix(router): drain only in-flight requests of muxes the graph server …
endigma Jul 9, 2026
2bedc2a
Expose health checks (#16)
budziam Jul 14, 2026
c662643
feat(mondaytweaks): skip CoordinateDependencies allocation via Disabl…
arutkowski00 Jul 15, 2026
18e34a2
fix(router): count fetch tree and response fields in plan cache cost …
arutkowski00 Jul 16, 2026
5882363
Merge remote-tracking branch 'origin/main' into monday-tweaks
budziam Jul 20, 2026
9cfc3fb
chore(mondaytweaks): remove shareUpstreamSubscriptionClient, asyncBou…
budziam Jul 20, 2026
1ec3d80
chore(mondaytweaks): reduce diff surface against upstream
budziam Jul 20, 2026
b69282d
Revert "patch https://monday.slack.com/archives/C09NXK51KR8/p17835232…
budziam Jul 20, 2026
8977681
Revert "Expose health checks (#16)"
budziam Jul 20, 2026
9cfbec6
chore(mondaytweaks): revert ResolveGraphqlFactory to upstream inline …
budziam Jul 20, 2026
ea1ef60
fix(mondaytweaks): restore accidentally dropped OnEvict nil-guard com…
budziam Jul 20, 2026
84abf0e
chore(mondaytweaks): remove remaining closeOnce remnant from b887fd8a9
budziam Jul 20, 2026
671ebdc
Merge branch 'wundergraph:main' into monday-tweaks
arutkowski00 Aug 31, 2026
7df21ad
fix(redis): use SUBSCRIBE not PSUBSCRIBE for ElastiCache Serverless c…
damian-rakus Sep 3, 2026
120e8fd
initial test
damian-rakus Sep 7, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import {
EDFS_NATS_STREAM_CONFIGURATION,
EDFS_NATS_SUBSCRIBE,
EDFS_REDIS_PUBLISH,
EDFS_PUSHER_SUBSCRIBE,
EDFS_REDIS_SUBSCRIBE,
ENUM_UPPER,
ENUM_VALUE_UPPER,
Expand Down Expand Up @@ -104,6 +105,7 @@ import {
EDFS_NATS_REQUEST_DEFINITION,
EDFS_NATS_SUBSCRIBE_DEFINITION,
EDFS_REDIS_PUBLISH_DEFINITION,
EDFS_PUSHER_SUBSCRIBE_DEFINITION,
EDFS_REDIS_SUBSCRIBE_DEFINITION,
EXTENDS_DEFINITION,
EXTERNAL_DEFINITION,
Expand Down Expand Up @@ -804,6 +806,44 @@ export const REDIS_SUBSCRIBE_DEFINITION_DATA = newDirectiveDefinitionData({
requiredArgumentNames: new Set<ArgumentName>([CHANNELS]),
});

export const PUSHER_SUBSCRIBE_DEFINITION_DATA = newDirectiveDefinitionData({
argumentDataByName: new Map<ArgumentName, DirectiveArgumentData>([
[
CHANNELS,
newDirectiveArgumentData({
directive: `@${EDFS_PUSHER_SUBSCRIBE}`,
name: CHANNELS,
namedTypeKind: Kind.SCALAR_TYPE_DEFINITION,
typeNode: {
kind: Kind.NON_NULL_TYPE,
type: {
kind: Kind.LIST_TYPE,
type: REQUIRED_STRING_TYPE_NODE,
},
},
}),
],
[
PROVIDER_ID,
newDirectiveArgumentData({
directive: `@${EDFS_PUSHER_SUBSCRIBE}`,
name: PROVIDER_ID,
namedTypeKind: Kind.SCALAR_TYPE_DEFINITION,
typeNode: REQUIRED_STRING_TYPE_NODE,
defaultValue: {
kind: Kind.STRING,
value: DEFAULT_EDFS_PROVIDER_ID,
},
}),
],
]),
locations: new Set<DirectiveLocation>([FIELD_DEFINITION_UPPER]),
name: EDFS_PUSHER_SUBSCRIBE,
node: EDFS_PUSHER_SUBSCRIBE_DEFINITION,
optionalArgumentNames: new Set<ArgumentName>([PROVIDER_ID]),
requiredArgumentNames: new Set<ArgumentName>([CHANNELS]),
});

export const REQUIRE_FETCH_REASONS_DEFINITION_DATA = newDirectiveDefinitionData({
isRepeatable: true,
locations: new Set<DirectiveLocation>([FIELD_DEFINITION_UPPER, INTERFACE_UPPER, OBJECT_UPPER]),
Expand Down
16 changes: 15 additions & 1 deletion composition/src/router-configuration/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ export type KafkaEventType = 'subscribe' | 'publish';

export type RedisEventType = 'subscribe' | 'publish';

export type PusherEventType = 'subscribe';

export type StreamConfiguration = {
consumerInactiveThreshold: number;
consumerName: string;
Expand Down Expand Up @@ -44,7 +46,19 @@ export type RedisEventConfiguration = {
type: RedisEventType;
};

export type EventConfiguration = KafkaEventConfiguration | NatsEventConfiguration | RedisEventConfiguration;
export type PusherEventConfiguration = {
fieldName: string;
providerId: string;
providerType: 'pusher';
channels: string[];
type: PusherEventType;
};

export type EventConfiguration =
| KafkaEventConfiguration
| NatsEventConfiguration
| RedisEventConfiguration
| PusherEventConfiguration;

export type SubscriptionFilterValue = boolean | null | number | string;

Expand Down
2 changes: 2 additions & 0 deletions composition/src/utils/string-constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ export const EDFS_PUBLISH_RESULT = 'edfs__PublishResult';
export const EDFS_NATS_STREAM_CONFIGURATION = 'edfs__NatsStreamConfiguration';
export const EDFS_REDIS_PUBLISH = 'edfs__redisPublish';
export const EDFS_REDIS_SUBSCRIBE = 'edfs__redisSubscribe';
export const EDFS_PUSHER_SUBSCRIBE = 'edfs__pusherSubscribe';
export const ENTITIES = 'entities';
export const ENTITIES_FIELD = '_entities';
export const OPENFED_ENTITY_CACHE = 'openfed__entityCache';
Expand Down Expand Up @@ -103,6 +104,7 @@ export const PROPAGATE = 'propagate';
export const PROVIDER_TYPE_KAFKA = 'kafka';
export const PROVIDER_TYPE_NATS = 'nats';
export const PROVIDER_TYPE_REDIS = 'redis';
export const PROVIDER_TYPE_PUSHER = 'pusher';
export const NOT_APPLICABLE = 'N/A';
export const NAME = 'name';
export const NEGATIVE_CACHE_TTL = 'negativeCacheTTL';
Expand Down
3 changes: 3 additions & 0 deletions composition/src/v1/constants/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import {
EDFS_NATS_REQUEST,
EDFS_NATS_SUBSCRIBE,
EDFS_REDIS_PUBLISH,
EDFS_PUSHER_SUBSCRIBE,
EDFS_REDIS_SUBSCRIBE,
EXTENDS,
EXTERNAL,
Expand Down Expand Up @@ -58,6 +59,7 @@ import {
EDFS_NATS_REQUEST_DEFINITION,
EDFS_NATS_SUBSCRIBE_DEFINITION,
EDFS_REDIS_PUBLISH_DEFINITION,
EDFS_PUSHER_SUBSCRIBE_DEFINITION,
EDFS_REDIS_SUBSCRIBE_DEFINITION,
EXTENDS_DEFINITION,
EXTERNAL_DEFINITION,
Expand Down Expand Up @@ -103,6 +105,7 @@ export const DIRECTIVE_DEFINITION_BY_NAME: ReadonlyMap<DirectiveName, DirectiveD
[EDFS_NATS_SUBSCRIBE, EDFS_NATS_SUBSCRIBE_DEFINITION],
[EDFS_REDIS_PUBLISH, EDFS_REDIS_PUBLISH_DEFINITION],
[EDFS_REDIS_SUBSCRIBE, EDFS_REDIS_SUBSCRIBE_DEFINITION],
[EDFS_PUSHER_SUBSCRIBE, EDFS_PUSHER_SUBSCRIBE_DEFINITION],
[EXTENDS, EXTENDS_DEFINITION],
[EXTERNAL, EXTERNAL_DEFINITION],
[INACCESSIBLE, INACCESSIBLE_DEFINITION],
Expand Down
31 changes: 31 additions & 0 deletions composition/src/v1/constants/directive-definitions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import {
EDFS_NATS_STREAM_CONFIGURATION,
EDFS_NATS_SUBSCRIBE,
EDFS_REDIS_PUBLISH,
EDFS_PUSHER_SUBSCRIBE,
EDFS_REDIS_SUBSCRIBE,
ENUM_UPPER,
ENUM_VALUE_UPPER,
Expand Down Expand Up @@ -488,6 +489,36 @@ export const EDFS_REDIS_SUBSCRIBE_DEFINITION: DirectiveDefinitionNode = {
repeatable: false,
};

// directive @edfs__pusherSubscribe(channels: [String!]!, providerId: String! = "default") on FIELD_DEFINITION
export const EDFS_PUSHER_SUBSCRIBE_DEFINITION: DirectiveDefinitionNode = {
arguments: [
{
kind: Kind.INPUT_VALUE_DEFINITION,
name: stringToNameNode(CHANNELS),
type: {
kind: Kind.NON_NULL_TYPE,
type: {
kind: Kind.LIST_TYPE,
type: REQUIRED_STRING_TYPE_NODE,
},
},
},
{
kind: Kind.INPUT_VALUE_DEFINITION,
name: stringToNameNode(PROVIDER_ID),
type: REQUIRED_STRING_TYPE_NODE,
defaultValue: {
kind: Kind.STRING,
value: DEFAULT_EDFS_PROVIDER_ID,
},
},
],
kind: Kind.DIRECTIVE_DEFINITION,
locations: [stringToNameNode(FIELD_DEFINITION_UPPER)],
name: stringToNameNode(EDFS_PUSHER_SUBSCRIBE),
repeatable: false,
};

export const INACCESSIBLE_DEFINITION: DirectiveDefinitionNode = {
kind: Kind.DIRECTIVE_DEFINITION,
locations: stringArrayToNameNodeArray([
Expand Down
2 changes: 2 additions & 0 deletions composition/src/v1/constants/strings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import {
EDFS_NATS_STREAM_CONFIGURATION,
EDFS_NATS_SUBSCRIBE,
EDFS_REDIS_PUBLISH,
EDFS_PUSHER_SUBSCRIBE,
EDFS_REDIS_SUBSCRIBE,
ENUM_UPPER,
ENUM_VALUE_UPPER,
Expand Down Expand Up @@ -84,6 +85,7 @@ export const EVENT_DIRECTIVE_NAMES: ReadonlySet<DirectiveName> = new Set<Directi
EDFS_NATS_REQUEST,
EDFS_NATS_SUBSCRIBE,
EDFS_REDIS_PUBLISH,
EDFS_PUSHER_SUBSCRIBE,
EDFS_REDIS_SUBSCRIBE,
]);

Expand Down
61 changes: 60 additions & 1 deletion composition/src/v1/normalization/normalization-factory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -294,6 +294,7 @@ import {
EDFS_NATS_SUBSCRIBE,
EDFS_PUBLISH_RESULT,
EDFS_REDIS_PUBLISH,
EDFS_PUSHER_SUBSCRIBE,
EDFS_REDIS_SUBSCRIBE,
ENTITIES_FIELD,
EXTENDS,
Expand Down Expand Up @@ -331,6 +332,7 @@ import {
PROVIDER_ID,
PROVIDER_TYPE_KAFKA,
PROVIDER_TYPE_NATS,
PROVIDER_TYPE_PUSHER,
PROVIDER_TYPE_REDIS,
PUBLISH,
QUERY,
Expand Down Expand Up @@ -3410,6 +3412,54 @@ export class NormalizationFactory {
};
}

getPusherSubscribeConfiguration(
directive: ConstDirectiveNode,
argumentDataByArgumentName: Map<string, InputValueData>,
fieldName: string,
errorMessages: string[],
): EventConfiguration | undefined {
const channels: string[] = [];
let providerId = DEFAULT_EDFS_PROVIDER_ID;
for (const argumentNode of directive.arguments || []) {
switch (argumentNode.name.value) {
case CHANNELS: {
//@TODO list coercion
if (argumentNode.value.kind !== Kind.LIST) {
errorMessages.push(invalidEventSubjectsErrorMessage(CHANNELS));
continue;
}
for (const value of argumentNode.value.values) {
if (value.kind !== Kind.STRING || value.value.length < 1) {
errorMessages.push(invalidEventSubjectsItemErrorMessage(CHANNELS));
break;
}
validateArgumentTemplateReferences(value.value, argumentDataByArgumentName, errorMessages);
channels.push(value.value);
}
break;
}
case PROVIDER_ID: {
if (argumentNode.value.kind !== Kind.STRING || argumentNode.value.value.length < 1) {
errorMessages.push(invalidEventProviderIdErrorMessage);
continue;
}
providerId = argumentNode.value.value;
break;
}
}
}
if (errorMessages.length > 0) {
return;
}
return {
fieldName,
providerId,
providerType: PROVIDER_TYPE_PUSHER,
channels,
type: SUBSCRIBE,
};
}

validateSubscriptionFilterDirectiveLocation(node: FieldDefinitionNode) {
if (!node.directives) {
return;
Expand Down Expand Up @@ -3505,6 +3555,15 @@ export class NormalizationFactory {
);
break;
}
case EDFS_PUSHER_SUBSCRIBE: {
eventConfiguration = this.getPusherSubscribeConfiguration(
directive,
argumentDataByArgumentName,
fieldName,
errorMessages,
);
break;
}
default:
continue;
}
Expand Down Expand Up @@ -3534,7 +3593,7 @@ export class NormalizationFactory {
case OperationTypeNode.QUERY:
return new Set<string>([EDFS_NATS_REQUEST]);
case OperationTypeNode.SUBSCRIPTION:
return new Set<string>([EDFS_KAFKA_SUBSCRIBE, EDFS_NATS_SUBSCRIBE, EDFS_REDIS_SUBSCRIBE]);
return new Set<string>([EDFS_KAFKA_SUBSCRIBE, EDFS_NATS_SUBSCRIBE, EDFS_REDIS_SUBSCRIBE, EDFS_PUSHER_SUBSCRIBE]);
}
}

Expand Down
3 changes: 3 additions & 0 deletions composition/src/v1/normalization/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ import {
OVERRIDE_DEFINITION_DATA,
PROVIDES_DEFINITION_DATA,
REDIS_PUBLISH_DEFINITION_DATA,
PUSHER_SUBSCRIBE_DEFINITION_DATA,
REDIS_SUBSCRIBE_DEFINITION_DATA,
REQUIRE_FETCH_REASONS_DEFINITION_DATA,
REQUIRES_DEFINITION_DATA,
Expand Down Expand Up @@ -96,6 +97,7 @@ import {
EDFS_NATS_REQUEST,
EDFS_NATS_SUBSCRIBE,
EDFS_REDIS_PUBLISH,
EDFS_PUSHER_SUBSCRIBE,
EDFS_REDIS_SUBSCRIBE,
EXTENDS,
EXTERNAL,
Expand Down Expand Up @@ -490,6 +492,7 @@ export function initializeDirectiveDefinitionDatas(): Map<string, DirectiveDefin
[EDFS_NATS_SUBSCRIBE, NATS_SUBSCRIBE_DEFINITION_DATA],
[EDFS_REDIS_PUBLISH, REDIS_PUBLISH_DEFINITION_DATA],
[EDFS_REDIS_SUBSCRIBE, REDIS_SUBSCRIBE_DEFINITION_DATA],
[EDFS_PUSHER_SUBSCRIBE, PUSHER_SUBSCRIBE_DEFINITION_DATA],
[EXTENDS, EXTENDS_DEFINITION_DATA],
[EXTERNAL, EXTERNAL_DEFINITION_DATA],
[INACCESSIBLE, INACCESSIBLE_DEFINITION_DATA],
Expand Down
69 changes: 48 additions & 21 deletions connect/src/wg/cosmo/node/v1/node_pb.ts

Large diffs are not rendered by default.

6 changes: 6 additions & 0 deletions proto/wg/cosmo/node/v1/node.proto
Original file line number Diff line number Diff line change
Expand Up @@ -466,6 +466,11 @@ message RedisEventConfiguration {
repeated string channels = 2;
}

message PusherEventConfiguration {
EngineEventConfiguration engine_event_configuration = 1;
repeated string channels = 2;
}

message EngineEventConfiguration {
string provider_id = 1;
EventType type = 2;
Expand All @@ -477,6 +482,7 @@ message DataSourceCustomEvents {
repeated NatsEventConfiguration nats = 1;
repeated KafkaEventConfiguration kafka = 2;
repeated RedisEventConfiguration redis = 3;
repeated PusherEventConfiguration pusher = 4;
}

message DataSourceCustom_Static {
Expand Down
2 changes: 1 addition & 1 deletion router-tests/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ require (
github.com/redis/go-redis/v9 v9.7.3
github.com/sebdah/goldie/v2 v2.7.1
github.com/stretchr/testify v1.11.1
github.com/tidwall/gjson v1.18.0
github.com/twmb/franz-go v1.16.1
github.com/twmb/franz-go/pkg/kadm v1.11.0
github.com/wundergraph/astjson v1.1.0
Expand Down Expand Up @@ -154,7 +155,6 @@ require (
github.com/sosodev/duration v1.3.1 // indirect
github.com/spf13/cast v1.7.1 // indirect
github.com/stretchr/objx v0.5.3 // indirect
github.com/tidwall/gjson v1.18.0 // indirect
github.com/tidwall/match v1.1.1 // indirect
github.com/tidwall/pretty v1.2.1 // indirect
github.com/tidwall/sjson v1.2.5 // indirect
Expand Down
28 changes: 28 additions & 0 deletions router-tests/modules/custom-set-wildcard-scope/module.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package custom_set_wildcard_scope

import (
"net/http"

"github.com/wundergraph/cosmo/router/core"
)

const myModuleID = "setWildcardScopeModule"

type SetWildcardScopeModule struct{}

func (m *SetWildcardScopeModule) Middleware(ctx core.RequestContext, next http.Handler) {
ctx.SetWildcardScope(true)
next.ServeHTTP(ctx.ResponseWriter(), ctx.Request())
}

func (m *SetWildcardScopeModule) Module() core.ModuleInfo {
return core.ModuleInfo{
ID: myModuleID,
Priority: 2,
New: func() core.Module {
return &SetWildcardScopeModule{}
},
}
}

var _ core.RouterMiddlewareHandler = (*SetWildcardScopeModule)(nil)
Loading
Loading