chore: import upstream snapshot with attribution
Publish CLI Package / publish-npm (push) Waiting to run
Publish Python SDK / publish-pypi (push) Waiting to run
Publish TypeScript SDK / publish-npm (push) Waiting to run
CI / Migrate Dev DB (push) Has been skipped
CI / Detect Version (push) Has been cancelled
CI / Migrate DB (push) Has been cancelled
CI / Build Dev ECR (./docker/app.Dockerfile, ECR_APP) (push) Has been cancelled
CI / Build Dev ECR (./docker/db.Dockerfile, ECR_MIGRATIONS) (push) Has been cancelled
CI / Build Dev ECR (./docker/pii.Dockerfile, ECR_PII) (push) Has been cancelled
CI / Build Dev ECR (./docker/realtime.Dockerfile, ECR_REALTIME) (push) Has been cancelled
CI / Deploy Trigger.dev (Dev) (push) Has been cancelled
CI / Build AMD64 (./docker/app.Dockerfile, ECR_APP, ghcr.io/simstudioai/simstudio) (push) Has been cancelled
CI / Build AMD64 (./docker/db.Dockerfile, ECR_MIGRATIONS, ghcr.io/simstudioai/migrations) (push) Has been cancelled
CI / Build AMD64 (./docker/pii.Dockerfile, ECR_PII, ghcr.io/simstudioai/pii) (push) Has been cancelled
CI / Build AMD64 (./docker/realtime.Dockerfile, ECR_REALTIME, ghcr.io/simstudioai/realtime) (push) Has been cancelled
CI / Build ARM64 (GHCR Only) (./docker/app.Dockerfile, ghcr.io/simstudioai/simstudio) (push) Has been cancelled
CI / Build ARM64 (GHCR Only) (./docker/db.Dockerfile, ghcr.io/simstudioai/migrations) (push) Has been cancelled
CI / Build ARM64 (GHCR Only) (./docker/pii.Dockerfile, ghcr.io/simstudioai/pii) (push) Has been cancelled
CI / Build ARM64 (GHCR Only) (./docker/realtime.Dockerfile, ghcr.io/simstudioai/realtime) (push) Has been cancelled
CI / Create GHCR Manifests (ghcr.io/simstudioai/migrations) (push) Has been cancelled
CI / Create GHCR Manifests (ghcr.io/simstudioai/pii) (push) Has been cancelled
CI / Create GHCR Manifests (ghcr.io/simstudioai/realtime) (push) Has been cancelled
CI / Create GHCR Manifests (ghcr.io/simstudioai/simstudio) (push) Has been cancelled
CI / Check Docs Changes (push) Has been cancelled
CI / Process Docs (push) Has been cancelled
CI / Create GitHub Release (push) Has been cancelled
CI / Test and Build (push) Has been cancelled

This commit is contained in:
wehub-resource-sync
2026-07-13 13:20:55 +08:00
commit d25d482dc2
13754 changed files with 4996608 additions and 0 deletions
+40
View File
@@ -0,0 +1,40 @@
{
"name": "@sim/realtime-protocol",
"version": "0.1.0",
"private": true,
"sideEffects": false,
"type": "module",
"license": "Apache-2.0",
"engines": {
"bun": ">=1.2.13",
"node": ">=20.0.0"
},
"exports": {
"./constants": {
"types": "./src/constants.ts",
"default": "./src/constants.ts"
},
"./events": {
"types": "./src/events.ts",
"default": "./src/events.ts"
},
"./schemas": {
"types": "./src/schemas.ts",
"default": "./src/schemas.ts"
}
},
"scripts": {
"type-check": "tsc --noEmit",
"lint": "biome check --write --unsafe .",
"lint:check": "biome check .",
"format": "biome format --write .",
"format:check": "biome format ."
},
"dependencies": {
"zod": "4.3.6"
},
"devDependencies": {
"@sim/tsconfig": "workspace:*",
"typescript": "^7.0.2"
}
}
+115
View File
@@ -0,0 +1,115 @@
export const BLOCK_OPERATIONS = {
UPDATE_POSITION: 'update-position',
UPDATE_NAME: 'update-name',
TOGGLE_ENABLED: 'toggle-enabled',
UPDATE_PARENT: 'update-parent',
UPDATE_ADVANCED_MODE: 'update-advanced-mode',
UPDATE_CANONICAL_MODE: 'update-canonical-mode',
REPLACE_CANONICAL_MODES: 'replace-canonical-modes',
TOGGLE_HANDLES: 'toggle-handles',
} as const
export type BlockOperation = (typeof BLOCK_OPERATIONS)[keyof typeof BLOCK_OPERATIONS]
export const BLOCKS_OPERATIONS = {
BATCH_UPDATE_POSITIONS: 'batch-update-positions',
BATCH_ADD_BLOCKS: 'batch-add-blocks',
BATCH_REMOVE_BLOCKS: 'batch-remove-blocks',
BATCH_TOGGLE_ENABLED: 'batch-toggle-enabled',
BATCH_TOGGLE_HANDLES: 'batch-toggle-handles',
BATCH_UPDATE_PARENT: 'batch-update-parent',
BATCH_TOGGLE_LOCKED: 'batch-toggle-locked',
} as const
export type BlocksOperation = (typeof BLOCKS_OPERATIONS)[keyof typeof BLOCKS_OPERATIONS]
export const EDGE_OPERATIONS = {
ADD: 'add',
REMOVE: 'remove',
} as const
export type EdgeOperation = (typeof EDGE_OPERATIONS)[keyof typeof EDGE_OPERATIONS]
export const EDGES_OPERATIONS = {
BATCH_ADD_EDGES: 'batch-add-edges',
BATCH_REMOVE_EDGES: 'batch-remove-edges',
} as const
export type EdgesOperation = (typeof EDGES_OPERATIONS)[keyof typeof EDGES_OPERATIONS]
export const SUBFLOW_OPERATIONS = {
UPDATE: 'update',
} as const
export type SubflowOperation = (typeof SUBFLOW_OPERATIONS)[keyof typeof SUBFLOW_OPERATIONS]
export const VARIABLE_OPERATIONS = {
ADD: 'add',
REMOVE: 'remove',
UPDATE: 'variable-update',
} as const
export type VariableOperation = (typeof VARIABLE_OPERATIONS)[keyof typeof VARIABLE_OPERATIONS]
export const WORKFLOW_OPERATIONS = {
REPLACE_STATE: 'replace-state',
} as const
export type WorkflowOperation = (typeof WORKFLOW_OPERATIONS)[keyof typeof WORKFLOW_OPERATIONS]
export const SUBBLOCK_OPERATIONS = {
UPDATE: 'subblock-update',
BATCH_UPDATE: 'subblock-batch-update',
} as const
export type SubblockOperation = (typeof SUBBLOCK_OPERATIONS)[keyof typeof SUBBLOCK_OPERATIONS]
export const OPERATION_TARGETS = {
BLOCK: 'block',
BLOCKS: 'blocks',
EDGE: 'edge',
EDGES: 'edges',
SUBBLOCK: 'subblock',
SUBFLOW: 'subflow',
VARIABLE: 'variable',
WORKFLOW: 'workflow',
} as const
export type OperationTarget = (typeof OPERATION_TARGETS)[keyof typeof OPERATION_TARGETS]
/** Undo/Redo operation types (includes some socket operations + undo-specific ones) */
export const UNDO_REDO_OPERATIONS = {
BATCH_ADD_BLOCKS: 'batch-add-blocks',
BATCH_REMOVE_BLOCKS: 'batch-remove-blocks',
BATCH_ADD_EDGES: 'batch-add-edges',
BATCH_REMOVE_EDGES: 'batch-remove-edges',
BATCH_MOVE_BLOCKS: 'batch-move-blocks',
UPDATE_PARENT: 'update-parent',
BATCH_UPDATE_PARENT: 'batch-update-parent',
BATCH_TOGGLE_ENABLED: 'batch-toggle-enabled',
BATCH_TOGGLE_HANDLES: 'batch-toggle-handles',
BATCH_TOGGLE_LOCKED: 'batch-toggle-locked',
BATCH_UPDATE_SUBBLOCKS: 'batch-update-subblocks',
APPLY_DIFF: 'apply-diff',
ACCEPT_DIFF: 'accept-diff',
REJECT_DIFF: 'reject-diff',
} as const
export type UndoRedoOperation = (typeof UNDO_REDO_OPERATIONS)[keyof typeof UNDO_REDO_OPERATIONS]
/**
* All socket operations that require permission checks.
* This is the single source of truth for valid operations.
*/
export const ALL_SOCKET_OPERATIONS = [
...Object.values(BLOCK_OPERATIONS),
...Object.values(BLOCKS_OPERATIONS),
...Object.values(EDGE_OPERATIONS),
...Object.values(EDGES_OPERATIONS),
...Object.values(WORKFLOW_OPERATIONS),
...Object.values(SUBBLOCK_OPERATIONS),
...Object.values(VARIABLE_OPERATIONS),
...Object.values(SUBFLOW_OPERATIONS),
] as const
export type SocketOperation = (typeof ALL_SOCKET_OPERATIONS)[number]
+122
View File
@@ -0,0 +1,122 @@
import type { OperationTarget, SocketOperation } from './constants'
/**
* Wire types for the broadcast/confirmation events the realtime Socket.IO server
* emits to clients. These mirror the exact object literals emitted by
* `apps/realtime/src/handlers/**` and `apps/realtime/src/rooms/**`, and are the
* canonical types consumed by the client socket transport
* (`apps/sim/app/workspace/providers/socket-provider.tsx`).
*
* Payload bodies that the transport forwards opaquely are typed `unknown` rather
* than a concrete operation union, because the transport never narrows them — the
* collaborative-workflow consumer dispatches on `operation`/`target` itself.
*/
/** A live-presence cursor position broadcast over the socket. */
export interface CursorPosition {
x: number
y: number
}
/** A live-presence selection broadcast over the socket. */
export interface PresenceSelection {
type: 'block' | 'edge' | 'none'
id?: string
}
/**
* `workflow-operation` broadcast. The server re-broadcasts the originating
* operation envelope plus sender identity and operation metadata.
*/
export interface WorkflowOperationBroadcast {
operation: SocketOperation | string
target: OperationTarget | string
payload: unknown
timestamp: number
senderId: string
userId: string
userName: string
metadata: {
workflowId: string
operationId: string
isPositionUpdate?: boolean
isBatchPositionUpdate?: boolean
}
}
/** `subblock-update` broadcast. */
export interface SubblockUpdateBroadcast {
workflowId: string
blockId: string
subblockId: string
value: unknown
timestamp: number
}
/** `variable-update` broadcast. */
export interface VariableUpdateBroadcast {
workflowId: string
variableId: string
field: string
value: unknown
timestamp: number
}
/** `cursor-update` presence broadcast for a single remote user. */
export interface CursorUpdateBroadcast {
socketId: string
userId: string
userName: string
avatarUrl?: string | null
/** `null` when the remote user's cursor leaves the canvas (the client emits `{ cursor: null }`). */
cursor: CursorPosition | null
}
/** `selection-update` presence broadcast for a single remote user. */
export interface SelectionUpdateBroadcast {
socketId: string
userId: string
userName: string
avatarUrl?: string | null
selection: PresenceSelection
}
/** `workflow-deleted` lifecycle broadcast. */
export interface WorkflowDeletedBroadcast {
workflowId: string
message: string
timestamp: number
}
/** `workflow-reverted` lifecycle broadcast. */
export interface WorkflowRevertedBroadcast {
workflowId: string
message: string
timestamp: number
}
/** `workflow-updated` lifecycle broadcast. */
export interface WorkflowUpdatedBroadcast {
workflowId: string
message: string
timestamp: number
}
/** `workflow-deployed` lifecycle broadcast. */
export interface WorkflowDeployedBroadcast {
workflowId: string
timestamp: number
}
/** `operation-confirmed` ack for a previously-emitted operation. */
export interface OperationConfirmedBroadcast {
operationId: string
serverTimestamp: number
}
/** `operation-failed` rejection for a previously-emitted operation. */
export interface OperationFailedBroadcast {
operationId: string
error: string
retryable?: boolean
}
+273
View File
@@ -0,0 +1,273 @@
import { z } from 'zod'
import {
BLOCK_OPERATIONS,
BLOCKS_OPERATIONS,
EDGE_OPERATIONS,
EDGES_OPERATIONS,
OPERATION_TARGETS,
SUBBLOCK_OPERATIONS,
SUBFLOW_OPERATIONS,
VARIABLE_OPERATIONS,
WORKFLOW_OPERATIONS,
} from './constants'
const PositionSchema = z.object({
x: z.number(),
y: z.number(),
})
const AutoConnectEdgeSchema = z.object({
id: z.string(),
source: z.string(),
target: z.string(),
sourceHandle: z.string().nullable().optional(),
targetHandle: z.string().nullable().optional(),
type: z.string().optional(),
})
export const BlockOperationSchema = z.object({
operation: z.enum([
BLOCK_OPERATIONS.UPDATE_POSITION,
BLOCK_OPERATIONS.UPDATE_NAME,
BLOCK_OPERATIONS.TOGGLE_ENABLED,
BLOCK_OPERATIONS.UPDATE_PARENT,
BLOCK_OPERATIONS.UPDATE_ADVANCED_MODE,
BLOCK_OPERATIONS.UPDATE_CANONICAL_MODE,
BLOCK_OPERATIONS.REPLACE_CANONICAL_MODES,
BLOCK_OPERATIONS.TOGGLE_HANDLES,
]),
target: z.literal(OPERATION_TARGETS.BLOCK),
payload: z.object({
id: z.string(),
type: z.string().optional(),
name: z.string().optional(),
position: PositionSchema.optional(),
commit: z.boolean().optional(),
data: z.record(z.string(), z.any()).optional(),
subBlocks: z.record(z.string(), z.any()).optional(),
outputs: z.record(z.string(), z.any()).optional(),
parentId: z.string().nullable().optional(),
extent: z.enum(['parent']).nullable().optional(),
enabled: z.boolean().optional(),
advancedMode: z.boolean().optional(),
horizontalHandles: z.boolean().optional(),
canonicalId: z.string().optional(),
canonicalMode: z.enum(['basic', 'advanced']).optional(),
triggerMode: z.boolean().optional(),
height: z.number().optional(),
}),
timestamp: z.number(),
operationId: z.string().optional(),
})
export const BatchPositionUpdateSchema = z.object({
operation: z.literal(BLOCKS_OPERATIONS.BATCH_UPDATE_POSITIONS),
target: z.literal(OPERATION_TARGETS.BLOCKS),
payload: z.object({
updates: z.array(
z.object({
id: z.string(),
position: PositionSchema,
})
),
}),
timestamp: z.number(),
operationId: z.string().optional(),
})
export const EdgeOperationSchema = z.object({
operation: z.enum([EDGE_OPERATIONS.ADD, EDGE_OPERATIONS.REMOVE]),
target: z.literal(OPERATION_TARGETS.EDGE),
payload: z.object({
id: z.string(),
source: z.string().optional(),
target: z.string().optional(),
sourceHandle: z.string().nullable().optional(),
targetHandle: z.string().nullable().optional(),
}),
timestamp: z.number(),
operationId: z.string().optional(),
})
export const SubflowOperationSchema = z.object({
operation: z.literal(SUBFLOW_OPERATIONS.UPDATE),
target: z.literal(OPERATION_TARGETS.SUBFLOW),
payload: z.object({
id: z.string(),
type: z.enum(['loop', 'parallel']).optional(),
config: z.record(z.string(), z.any()).optional(),
}),
timestamp: z.number(),
operationId: z.string().optional(),
})
export const VariableOperationSchema = z.union([
z.object({
operation: z.literal(VARIABLE_OPERATIONS.ADD),
target: z.literal(OPERATION_TARGETS.VARIABLE),
payload: z.object({
id: z.string(),
name: z.string(),
type: z.any(),
value: z.any(),
workflowId: z.string(),
}),
timestamp: z.number(),
operationId: z.string().optional(),
}),
z.object({
operation: z.literal(VARIABLE_OPERATIONS.REMOVE),
target: z.literal(OPERATION_TARGETS.VARIABLE),
payload: z.object({
variableId: z.string(),
}),
timestamp: z.number(),
operationId: z.string().optional(),
}),
])
export const WorkflowStateOperationSchema = z.object({
operation: z.literal(WORKFLOW_OPERATIONS.REPLACE_STATE),
target: z.literal(OPERATION_TARGETS.WORKFLOW),
payload: z.object({
state: z.any(),
}),
timestamp: z.number(),
operationId: z.string().optional(),
})
export const SubblockOperationSchema = z.object({
operation: z.literal(SUBBLOCK_OPERATIONS.BATCH_UPDATE),
target: z.literal(OPERATION_TARGETS.SUBBLOCK),
payload: z.object({
updates: z.array(
z.object({
blockId: z.string(),
subblockId: z.string(),
value: z.any(),
expectedValue: z.any().optional(),
})
),
}),
timestamp: z.number(),
operationId: z.string().optional(),
})
export const BatchAddBlocksSchema = z.object({
operation: z.literal(BLOCKS_OPERATIONS.BATCH_ADD_BLOCKS),
target: z.literal(OPERATION_TARGETS.BLOCKS),
payload: z.object({
blocks: z.array(z.record(z.string(), z.any())),
edges: z.array(AutoConnectEdgeSchema).optional(),
loops: z.record(z.string(), z.any()).optional(),
parallels: z.record(z.string(), z.any()).optional(),
subBlockValues: z.record(z.string(), z.record(z.string(), z.any())).optional(),
}),
timestamp: z.number(),
operationId: z.string().optional(),
})
export const BatchRemoveBlocksSchema = z.object({
operation: z.literal(BLOCKS_OPERATIONS.BATCH_REMOVE_BLOCKS),
target: z.literal(OPERATION_TARGETS.BLOCKS),
payload: z.object({
ids: z.array(z.string()),
}),
timestamp: z.number(),
operationId: z.string().optional(),
})
export const BatchRemoveEdgesSchema = z.object({
operation: z.literal(EDGES_OPERATIONS.BATCH_REMOVE_EDGES),
target: z.literal(OPERATION_TARGETS.EDGES),
payload: z.object({
ids: z.array(z.string()),
}),
timestamp: z.number(),
operationId: z.string().optional(),
})
export const BatchAddEdgesSchema = z.object({
operation: z.literal(EDGES_OPERATIONS.BATCH_ADD_EDGES),
target: z.literal(OPERATION_TARGETS.EDGES),
payload: z.object({
edges: z.array(
z.object({
id: z.string(),
source: z.string(),
target: z.string(),
sourceHandle: z.string().nullable().optional(),
targetHandle: z.string().nullable().optional(),
})
),
}),
timestamp: z.number(),
operationId: z.string().optional(),
})
export const BatchToggleEnabledSchema = z.object({
operation: z.literal(BLOCKS_OPERATIONS.BATCH_TOGGLE_ENABLED),
target: z.literal(OPERATION_TARGETS.BLOCKS),
payload: z.object({
blockIds: z.array(z.string()),
previousStates: z.record(z.string(), z.boolean()),
}),
timestamp: z.number(),
operationId: z.string().optional(),
})
export const BatchToggleHandlesSchema = z.object({
operation: z.literal(BLOCKS_OPERATIONS.BATCH_TOGGLE_HANDLES),
target: z.literal(OPERATION_TARGETS.BLOCKS),
payload: z.object({
blockIds: z.array(z.string()),
previousStates: z.record(z.string(), z.boolean()),
}),
timestamp: z.number(),
operationId: z.string().optional(),
})
export const BatchToggleLockedSchema = z.object({
operation: z.literal(BLOCKS_OPERATIONS.BATCH_TOGGLE_LOCKED),
target: z.literal(OPERATION_TARGETS.BLOCKS),
payload: z.object({
blockIds: z.array(z.string()),
previousStates: z.record(z.string(), z.boolean()),
}),
timestamp: z.number(),
operationId: z.string().optional(),
})
export const BatchUpdateParentSchema = z.object({
operation: z.literal(BLOCKS_OPERATIONS.BATCH_UPDATE_PARENT),
target: z.literal(OPERATION_TARGETS.BLOCKS),
payload: z.object({
updates: z.array(
z.object({
id: z.string(),
parentId: z.string(),
position: PositionSchema,
})
),
}),
timestamp: z.number(),
operationId: z.string().optional(),
})
export const WorkflowOperationSchema = z.union([
BlockOperationSchema,
BatchPositionUpdateSchema,
BatchAddBlocksSchema,
BatchRemoveBlocksSchema,
BatchToggleEnabledSchema,
BatchToggleHandlesSchema,
BatchToggleLockedSchema,
BatchUpdateParentSchema,
EdgeOperationSchema,
BatchAddEdgesSchema,
BatchRemoveEdgesSchema,
SubflowOperationSchema,
VariableOperationSchema,
WorkflowStateOperationSchema,
SubblockOperationSchema,
])
+5
View File
@@ -0,0 +1,5 @@
{
"extends": "@sim/tsconfig/library.json",
"include": ["src/**/*"],
"exclude": ["node_modules", "dist"]
}