@agent-native/core 0.30.6 → 0.31.1
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/a2a/client.d.ts +2 -0
- package/dist/a2a/client.d.ts.map +1 -1
- package/dist/a2a/client.js +7 -5
- package/dist/a2a/client.js.map +1 -1
- package/dist/a2a/handlers.d.ts.map +1 -1
- package/dist/a2a/handlers.js +3 -0
- package/dist/a2a/handlers.js.map +1 -1
- package/dist/a2a/server.d.ts.map +1 -1
- package/dist/a2a/server.js.map +1 -1
- package/dist/a2a/task-store.d.ts.map +1 -1
- package/dist/a2a/task-store.js +5 -1
- package/dist/a2a/task-store.js.map +1 -1
- package/dist/action.js +22 -4
- package/dist/action.js.map +1 -1
- package/dist/agent/engine/ai-sdk-engine.d.ts.map +1 -1
- package/dist/agent/engine/ai-sdk-engine.js +5 -0
- package/dist/agent/engine/ai-sdk-engine.js.map +1 -1
- package/dist/agent/engine/anthropic-engine.d.ts.map +1 -1
- package/dist/agent/engine/anthropic-engine.js +0 -7
- package/dist/agent/engine/anthropic-engine.js.map +1 -1
- package/dist/agent/engine/builder-engine.d.ts.map +1 -1
- package/dist/agent/engine/builder-engine.js +4 -0
- package/dist/agent/engine/builder-engine.js.map +1 -1
- package/dist/agent/engine/registry.d.ts.map +1 -1
- package/dist/agent/engine/registry.js.map +1 -1
- package/dist/agent/engine/translate-ai-sdk.d.ts.map +1 -1
- package/dist/agent/engine/translate-ai-sdk.js +5 -3
- package/dist/agent/engine/translate-ai-sdk.js.map +1 -1
- package/dist/agent/production-agent.d.ts.map +1 -1
- package/dist/agent/production-agent.js +31 -4
- package/dist/agent/production-agent.js.map +1 -1
- package/dist/agent/run-manager.d.ts.map +1 -1
- package/dist/agent/run-manager.js +21 -8
- package/dist/agent/run-manager.js.map +1 -1
- package/dist/agent/run-store.d.ts.map +1 -1
- package/dist/agent/run-store.js +5 -1
- package/dist/agent/run-store.js.map +1 -1
- package/dist/agent/tool-search.js.map +1 -1
- package/dist/application-state/store.d.ts.map +1 -1
- package/dist/application-state/store.js +18 -7
- package/dist/application-state/store.js.map +1 -1
- package/dist/brand-kit/brand-signals.d.ts +31 -0
- package/dist/brand-kit/brand-signals.d.ts.map +1 -0
- package/dist/brand-kit/brand-signals.js +101 -0
- package/dist/brand-kit/brand-signals.js.map +1 -0
- package/dist/brand-kit/index.d.ts +21 -0
- package/dist/brand-kit/index.d.ts.map +1 -0
- package/dist/brand-kit/index.js +34 -0
- package/dist/brand-kit/index.js.map +1 -0
- package/dist/brand-kit/types.d.ts +103 -0
- package/dist/brand-kit/types.d.ts.map +1 -0
- package/dist/brand-kit/types.js +17 -0
- package/dist/brand-kit/types.js.map +1 -0
- package/dist/browser-sessions/store.d.ts.map +1 -1
- package/dist/browser-sessions/store.js +6 -1
- package/dist/browser-sessions/store.js.map +1 -1
- package/dist/chat-threads/store.d.ts.map +1 -1
- package/dist/chat-threads/store.js +6 -2
- package/dist/chat-threads/store.js.map +1 -1
- package/dist/checkpoints/store.d.ts.map +1 -1
- package/dist/checkpoints/store.js +5 -1
- package/dist/checkpoints/store.js.map +1 -1
- package/dist/cli/code-agent-executor.d.ts.map +1 -1
- package/dist/cli/code-agent-executor.js.map +1 -1
- package/dist/cli/create.d.ts.map +1 -1
- package/dist/cli/create.js +0 -1
- package/dist/cli/create.js.map +1 -1
- package/dist/client/AgentNative.js.map +1 -1
- package/dist/client/AgentPanel.d.ts.map +1 -1
- package/dist/client/AgentPanel.js +18 -20
- package/dist/client/AgentPanel.js.map +1 -1
- package/dist/client/AssistantChat.d.ts.map +1 -1
- package/dist/client/AssistantChat.js +69 -17
- package/dist/client/AssistantChat.js.map +1 -1
- package/dist/client/IframeEmbed.d.ts.map +1 -1
- package/dist/client/IframeEmbed.js.map +1 -1
- package/dist/client/MultiTabAssistantChat.d.ts.map +1 -1
- package/dist/client/MultiTabAssistantChat.js +1 -1
- package/dist/client/MultiTabAssistantChat.js.map +1 -1
- package/dist/client/RunStuckBanner.js.map +1 -1
- package/dist/client/agent-chat.d.ts +0 -3
- package/dist/client/agent-chat.d.ts.map +1 -1
- package/dist/client/agent-chat.js +0 -3
- package/dist/client/agent-chat.js.map +1 -1
- package/dist/client/builder-mark.d.ts.map +1 -1
- package/dist/client/builder-mark.js.map +1 -1
- package/dist/client/components/CodeRequiredDialog.js +0 -7
- package/dist/client/components/CodeRequiredDialog.js.map +1 -1
- package/dist/client/components/MissingKeyCard.d.ts.map +1 -1
- package/dist/client/components/MissingKeyCard.js.map +1 -1
- package/dist/client/composer/PromptComposer.d.ts.map +1 -1
- package/dist/client/composer/PromptComposer.js +6 -3
- package/dist/client/composer/PromptComposer.js.map +1 -1
- package/dist/client/composer/TiptapComposer.d.ts.map +1 -1
- package/dist/client/composer/TiptapComposer.js +5 -0
- package/dist/client/composer/TiptapComposer.js.map +1 -1
- package/dist/client/composer/VoiceButton.d.ts.map +1 -1
- package/dist/client/composer/VoiceButton.js +9 -0
- package/dist/client/composer/VoiceButton.js.map +1 -1
- package/dist/client/composer/extensions/FileReference.d.ts.map +1 -1
- package/dist/client/composer/extensions/FileReference.js.map +1 -1
- package/dist/client/composer/extensions/MentionReference.d.ts.map +1 -1
- package/dist/client/composer/extensions/MentionReference.js.map +1 -1
- package/dist/client/composer/extensions/SkillReference.d.ts.map +1 -1
- package/dist/client/composer/extensions/SkillReference.js.map +1 -1
- package/dist/client/composer/use-file-search.d.ts.map +1 -1
- package/dist/client/composer/use-file-search.js +14 -3
- package/dist/client/composer/use-file-search.js.map +1 -1
- package/dist/client/conversation/AgentConversation.js +8 -6
- package/dist/client/conversation/AgentConversation.js.map +1 -1
- package/dist/client/conversation/use-near-bottom-autoscroll.d.ts.map +1 -1
- package/dist/client/conversation/use-near-bottom-autoscroll.js +133 -35
- package/dist/client/conversation/use-near-bottom-autoscroll.js.map +1 -1
- package/dist/client/db-admin/DbAdminPage.js.map +1 -1
- package/dist/client/db-admin/EditableCell.js +1 -1
- package/dist/client/db-admin/EditableCell.js.map +1 -1
- package/dist/client/dev-overlay/DevOverlay.d.ts +0 -2
- package/dist/client/dev-overlay/DevOverlay.d.ts.map +1 -1
- package/dist/client/dev-overlay/DevOverlay.js +1 -2
- package/dist/client/dev-overlay/DevOverlay.js.map +1 -1
- package/dist/client/extensions/EmbeddedExtension.d.ts.map +1 -1
- package/dist/client/extensions/EmbeddedExtension.js +19 -0
- package/dist/client/extensions/EmbeddedExtension.js.map +1 -1
- package/dist/client/extensions/ExtensionViewer.d.ts.map +1 -1
- package/dist/client/extensions/ExtensionViewer.js +11 -3
- package/dist/client/extensions/ExtensionViewer.js.map +1 -1
- package/dist/client/integrations/IntegrationsPanel.d.ts.map +1 -1
- package/dist/client/integrations/IntegrationsPanel.js.map +1 -1
- package/dist/client/mcp-app-host.d.ts.map +1 -1
- package/dist/client/mcp-app-host.js +25 -3
- package/dist/client/mcp-app-host.js.map +1 -1
- package/dist/client/mcp-apps/McpAppRenderer.d.ts.map +1 -1
- package/dist/client/mcp-apps/McpAppRenderer.js +1 -1
- package/dist/client/mcp-apps/McpAppRenderer.js.map +1 -1
- package/dist/client/notifications/NotificationsBell.js.map +1 -1
- package/dist/client/onboarding/SetupButton.d.ts.map +1 -1
- package/dist/client/onboarding/SetupButton.js +6 -0
- package/dist/client/onboarding/SetupButton.js.map +1 -1
- package/dist/client/progress/RunsTray.js.map +1 -1
- package/dist/client/resources/McpServerDetail.d.ts.map +1 -1
- package/dist/client/resources/McpServerDetail.js.map +1 -1
- package/dist/client/resources/ResourcesPanel.d.ts.map +1 -1
- package/dist/client/resources/ResourcesPanel.js +0 -1
- package/dist/client/resources/ResourcesPanel.js.map +1 -1
- package/dist/client/settings/AgentsSection.d.ts.map +1 -1
- package/dist/client/settings/AgentsSection.js +1 -1
- package/dist/client/settings/AgentsSection.js.map +1 -1
- package/dist/client/settings/AutomationsSection.js.map +1 -1
- package/dist/client/settings/SettingsPanel.js +2 -2
- package/dist/client/settings/SettingsPanel.js.map +1 -1
- package/dist/client/sharing/ShareButton.d.ts.map +1 -1
- package/dist/client/sharing/ShareButton.js +0 -4
- package/dist/client/sharing/ShareButton.js.map +1 -1
- package/dist/client/sse-event-processor.d.ts.map +1 -1
- package/dist/client/sse-event-processor.js +13 -3
- package/dist/client/sse-event-processor.js.map +1 -1
- package/dist/client/terminal/AgentTerminal.d.ts.map +1 -1
- package/dist/client/terminal/AgentTerminal.js +1 -1
- package/dist/client/terminal/AgentTerminal.js.map +1 -1
- package/dist/client/use-agent-chat.d.ts.map +1 -1
- package/dist/client/use-agent-chat.js +20 -4
- package/dist/client/use-agent-chat.js.map +1 -1
- package/dist/client/use-chat-threads.d.ts.map +1 -1
- package/dist/client/use-chat-threads.js +39 -25
- package/dist/client/use-chat-threads.js.map +1 -1
- package/dist/client/use-db-sync.d.ts.map +1 -1
- package/dist/client/use-db-sync.js +24 -0
- package/dist/client/use-db-sync.js.map +1 -1
- package/dist/client/use-dev-mode.d.ts.map +1 -1
- package/dist/client/use-dev-mode.js +25 -9
- package/dist/client/use-dev-mode.js.map +1 -1
- package/dist/client/use-run-stuck-detection.d.ts.map +1 -1
- package/dist/client/use-run-stuck-detection.js +7 -1
- package/dist/client/use-run-stuck-detection.js.map +1 -1
- package/dist/client/useProductionAgent.d.ts.map +1 -1
- package/dist/client/useProductionAgent.js +6 -2
- package/dist/client/useProductionAgent.js.map +1 -1
- package/dist/collab/agent-presence.d.ts +0 -3
- package/dist/collab/agent-presence.d.ts.map +1 -1
- package/dist/collab/agent-presence.js +3 -5
- package/dist/collab/agent-presence.js.map +1 -1
- package/dist/collab/awareness.d.ts.map +1 -1
- package/dist/collab/awareness.js +11 -1
- package/dist/collab/awareness.js.map +1 -1
- package/dist/collab/client-struct.js.map +1 -1
- package/dist/collab/storage.d.ts.map +1 -1
- package/dist/collab/storage.js +5 -1
- package/dist/collab/storage.js.map +1 -1
- package/dist/collab/ydoc-manager.d.ts.map +1 -1
- package/dist/collab/ydoc-manager.js +35 -8
- package/dist/collab/ydoc-manager.js.map +1 -1
- package/dist/deploy/build.js +0 -5
- package/dist/deploy/build.js.map +1 -1
- package/dist/extensions/content-patch.js +1 -1
- package/dist/extensions/content-patch.js.map +1 -1
- package/dist/extensions/fetch-tool.d.ts.map +1 -1
- package/dist/extensions/fetch-tool.js +4 -1
- package/dist/extensions/fetch-tool.js.map +1 -1
- package/dist/extensions/routes.js +12 -12
- package/dist/extensions/routes.js.map +1 -1
- package/dist/extensions/slots/store.d.ts.map +1 -1
- package/dist/extensions/slots/store.js +5 -1
- package/dist/extensions/slots/store.js.map +1 -1
- package/dist/file-upload/actions/upload-image.d.ts.map +1 -1
- package/dist/file-upload/actions/upload-image.js +39 -4
- package/dist/file-upload/actions/upload-image.js.map +1 -1
- package/dist/integrations/a2a-continuations-store.d.ts.map +1 -1
- package/dist/integrations/a2a-continuations-store.js +5 -1
- package/dist/integrations/a2a-continuations-store.js.map +1 -1
- package/dist/integrations/adapters/email.d.ts.map +1 -1
- package/dist/integrations/adapters/email.js +5 -2
- package/dist/integrations/adapters/email.js.map +1 -1
- package/dist/integrations/adapters/slack.d.ts.map +1 -1
- package/dist/integrations/adapters/slack.js.map +1 -1
- package/dist/integrations/google-docs-poller.d.ts.map +1 -1
- package/dist/integrations/google-docs-poller.js +16 -5
- package/dist/integrations/google-docs-poller.js.map +1 -1
- package/dist/integrations/pending-tasks-retry-job.d.ts.map +1 -1
- package/dist/integrations/pending-tasks-retry-job.js +6 -2
- package/dist/integrations/pending-tasks-retry-job.js.map +1 -1
- package/dist/integrations/pending-tasks-store.d.ts.map +1 -1
- package/dist/integrations/pending-tasks-store.js +5 -1
- package/dist/integrations/pending-tasks-store.js.map +1 -1
- package/dist/integrations/plugin.d.ts.map +1 -1
- package/dist/integrations/plugin.js +14 -3
- package/dist/integrations/plugin.js.map +1 -1
- package/dist/integrations/remote-commands-store.d.ts.map +1 -1
- package/dist/integrations/remote-commands-store.js +5 -1
- package/dist/integrations/remote-commands-store.js.map +1 -1
- package/dist/integrations/remote-devices-store.d.ts.map +1 -1
- package/dist/integrations/remote-devices-store.js +5 -1
- package/dist/integrations/remote-devices-store.js.map +1 -1
- package/dist/integrations/remote-push-store.d.ts.map +1 -1
- package/dist/integrations/remote-push-store.js +5 -1
- package/dist/integrations/remote-push-store.js.map +1 -1
- package/dist/integrations/remote-retry-job.js +1 -1
- package/dist/integrations/remote-retry-job.js.map +1 -1
- package/dist/integrations/remote-run-events-store.d.ts.map +1 -1
- package/dist/integrations/remote-run-events-store.js +5 -1
- package/dist/integrations/remote-run-events-store.js.map +1 -1
- package/dist/integrations/thread-mapping-store.d.ts.map +1 -1
- package/dist/integrations/thread-mapping-store.js +5 -1
- package/dist/integrations/thread-mapping-store.js.map +1 -1
- package/dist/integrations/webhook-handler.d.ts.map +1 -1
- package/dist/integrations/webhook-handler.js +10 -1
- package/dist/integrations/webhook-handler.js.map +1 -1
- package/dist/jobs/scheduler.d.ts.map +1 -1
- package/dist/jobs/scheduler.js +31 -15
- package/dist/jobs/scheduler.js.map +1 -1
- package/dist/jobs/tools.d.ts.map +1 -1
- package/dist/jobs/tools.js +4 -1
- package/dist/jobs/tools.js.map +1 -1
- package/dist/mcp/build-server.d.ts.map +1 -1
- package/dist/mcp/build-server.js +24 -9
- package/dist/mcp/build-server.js.map +1 -1
- package/dist/mcp/connect-store.d.ts +3 -4
- package/dist/mcp/connect-store.d.ts.map +1 -1
- package/dist/mcp/connect-store.js +5 -5
- package/dist/mcp/connect-store.js.map +1 -1
- package/dist/mcp-client/routes.js +6 -1
- package/dist/mcp-client/routes.js.map +1 -1
- package/dist/notifications/channels.d.ts.map +1 -1
- package/dist/notifications/channels.js +3 -2
- package/dist/notifications/channels.js.map +1 -1
- package/dist/oauth-tokens/store.d.ts.map +1 -1
- package/dist/oauth-tokens/store.js +5 -1
- package/dist/oauth-tokens/store.js.map +1 -1
- package/dist/observability/evals.d.ts.map +1 -1
- package/dist/observability/evals.js +7 -7
- package/dist/observability/evals.js.map +1 -1
- package/dist/observability/traces.d.ts.map +1 -1
- package/dist/observability/traces.js +15 -5
- package/dist/observability/traces.js.map +1 -1
- package/dist/org/accept-pending.js +1 -1
- package/dist/org/accept-pending.js.map +1 -1
- package/dist/org/handlers.d.ts.map +1 -1
- package/dist/org/handlers.js +3 -2
- package/dist/org/handlers.js.map +1 -1
- package/dist/progress/store.d.ts.map +1 -1
- package/dist/progress/store.js +11 -1
- package/dist/progress/store.js.map +1 -1
- package/dist/resources/handlers.d.ts +5 -5
- package/dist/resources/handlers.d.ts.map +1 -1
- package/dist/resources/handlers.js +0 -2
- package/dist/resources/handlers.js.map +1 -1
- package/dist/resources/store.d.ts.map +1 -1
- package/dist/resources/store.js +23 -13
- package/dist/resources/store.js.map +1 -1
- package/dist/scripts/db/query.d.ts.map +1 -1
- package/dist/scripts/db/query.js +1 -2
- package/dist/scripts/db/query.js.map +1 -1
- package/dist/scripts/db/schema.js.map +1 -1
- package/dist/server/action-discovery.d.ts.map +1 -1
- package/dist/server/action-discovery.js +10 -3
- package/dist/server/action-discovery.js.map +1 -1
- package/dist/server/agent-chat-plugin.d.ts.map +1 -1
- package/dist/server/agent-chat-plugin.js +3 -6
- package/dist/server/agent-chat-plugin.js.map +1 -1
- package/dist/server/auth.d.ts.map +1 -1
- package/dist/server/auth.js +13 -9
- package/dist/server/auth.js.map +1 -1
- package/dist/server/better-auth-instance.d.ts.map +1 -1
- package/dist/server/better-auth-instance.js +0 -3
- package/dist/server/better-auth-instance.js.map +1 -1
- package/dist/server/core-routes-plugin.d.ts.map +1 -1
- package/dist/server/core-routes-plugin.js +1 -2
- package/dist/server/core-routes-plugin.js.map +1 -1
- package/dist/server/create-server.d.ts.map +1 -1
- package/dist/server/create-server.js +0 -23
- package/dist/server/create-server.js.map +1 -1
- package/dist/server/google-oauth.d.ts.map +1 -1
- package/dist/server/google-oauth.js +0 -3
- package/dist/server/google-oauth.js.map +1 -1
- package/dist/server/identity-sso-store.d.ts.map +1 -1
- package/dist/server/identity-sso-store.js +14 -3
- package/dist/server/identity-sso-store.js.map +1 -1
- package/dist/server/poll.d.ts.map +1 -1
- package/dist/server/poll.js +67 -18
- package/dist/server/poll.js.map +1 -1
- package/dist/server/schema-prompt.js +1 -1
- package/dist/server/schema-prompt.js.map +1 -1
- package/dist/server/security-headers.d.ts +5 -4
- package/dist/server/security-headers.d.ts.map +1 -1
- package/dist/server/security-headers.js +5 -4
- package/dist/server/security-headers.js.map +1 -1
- package/dist/settings/store.d.ts.map +1 -1
- package/dist/settings/store.js +5 -1
- package/dist/settings/store.js.map +1 -1
- package/dist/sharing/access.d.ts.map +1 -1
- package/dist/sharing/access.js +25 -4
- package/dist/sharing/access.js.map +1 -1
- package/dist/sharing/actions/set-resource-visibility.d.ts.map +1 -1
- package/dist/sharing/actions/set-resource-visibility.js +8 -1
- package/dist/sharing/actions/set-resource-visibility.js.map +1 -1
- package/dist/triggers/actions.d.ts.map +1 -1
- package/dist/triggers/actions.js +1 -2
- package/dist/triggers/actions.js.map +1 -1
- package/dist/triggers/dispatcher.d.ts.map +1 -1
- package/dist/triggers/dispatcher.js +36 -8
- package/dist/triggers/dispatcher.js.map +1 -1
- package/dist/usage/store.d.ts.map +1 -1
- package/dist/usage/store.js +5 -1
- package/dist/usage/store.js.map +1 -1
- package/dist/vite/client.d.ts.map +1 -1
- package/dist/vite/client.js +7 -5
- package/dist/vite/client.js.map +1 -1
- package/package.json +3 -2
- package/dist/client/conversation/AgentConversation.spec.d.ts +0 -2
- package/dist/client/conversation/AgentConversation.spec.d.ts.map +0 -1
- package/dist/client/conversation/AgentConversation.spec.js +0 -69
- package/dist/client/conversation/AgentConversation.spec.js.map +0 -1
- package/dist/client/extensions/AgentNativeExtensionFrame.e2e-host.d.ts +0 -2
- package/dist/client/extensions/AgentNativeExtensionFrame.e2e-host.d.ts.map +0 -1
- package/dist/client/extensions/AgentNativeExtensionFrame.e2e-host.js +0 -110
- package/dist/client/extensions/AgentNativeExtensionFrame.e2e-host.js.map +0 -1
- package/dist/client/extensions/AgentNativeExtensionFrame.spec.d.ts +0 -2
- package/dist/client/extensions/AgentNativeExtensionFrame.spec.d.ts.map +0 -1
- package/dist/client/extensions/AgentNativeExtensionFrame.spec.js +0 -68
- package/dist/client/extensions/AgentNativeExtensionFrame.spec.js.map +0 -1
- package/dist/client/extensions/ExtensionViewer.spec.d.ts +0 -2
- package/dist/client/extensions/ExtensionViewer.spec.d.ts.map +0 -1
- package/dist/client/extensions/ExtensionViewer.spec.js +0 -94
- package/dist/client/extensions/ExtensionViewer.spec.js.map +0 -1
- package/dist/client/guided-questions.flow.spec.d.ts +0 -2
- package/dist/client/guided-questions.flow.spec.d.ts.map +0 -1
- package/dist/client/guided-questions.flow.spec.js +0 -147
- package/dist/client/guided-questions.flow.spec.js.map +0 -1
- package/dist/client/settings/useBuilderStatus.spec.d.ts +0 -2
- package/dist/client/settings/useBuilderStatus.spec.d.ts.map +0 -1
- package/dist/client/settings/useBuilderStatus.spec.js +0 -487
- package/dist/client/settings/useBuilderStatus.spec.js.map +0 -1
- package/dist/client/sharing/ShareButton.spec.d.ts +0 -2
- package/dist/client/sharing/ShareButton.spec.d.ts.map +0 -1
- package/dist/client/sharing/ShareButton.spec.js +0 -196
- package/dist/client/sharing/ShareButton.spec.js.map +0 -1
- package/dist/client/use-chat-models.spec.d.ts +0 -2
- package/dist/client/use-chat-models.spec.d.ts.map +0 -1
- package/dist/client/use-chat-models.spec.js +0 -39
- package/dist/client/use-chat-models.spec.js.map +0 -1
- package/dist/client/use-chat-threads.spec.d.ts +0 -2
- package/dist/client/use-chat-threads.spec.d.ts.map +0 -1
- package/dist/client/use-chat-threads.spec.js +0 -760
- package/dist/client/use-chat-threads.spec.js.map +0 -1
- package/dist/client/use-db-sync.spec.d.ts +0 -2
- package/dist/client/use-db-sync.spec.d.ts.map +0 -1
- package/dist/client/use-db-sync.spec.js +0 -107
- package/dist/client/use-db-sync.spec.js.map +0 -1
- package/dist/server/script-discovery.d.ts +0 -6
- package/dist/server/script-discovery.d.ts.map +0 -1
- package/dist/server/script-discovery.js +0 -6
- package/dist/server/script-discovery.js.map +0 -1
|
@@ -12,6 +12,11 @@ const DEFAULT_FIELD = "content";
|
|
|
12
12
|
const MAX_CACHE = 50;
|
|
13
13
|
const _cache = new Map();
|
|
14
14
|
const _writeLocks = new Map();
|
|
15
|
+
// Coalesces concurrent cache-miss loads for the same docId. Without this, two
|
|
16
|
+
// simultaneous getDoc() callers both miss the cache, both build a Y.Doc and
|
|
17
|
+
// apply stored state, and the second _cache.set silently orphans the first
|
|
18
|
+
// doc (a memory leak that grows with concurrent read traffic).
|
|
19
|
+
const _loadLocks = new Map();
|
|
15
20
|
function evictIfNeeded() {
|
|
16
21
|
if (_cache.size <= MAX_CACHE)
|
|
17
22
|
return;
|
|
@@ -77,14 +82,33 @@ export async function getDoc(docId) {
|
|
|
77
82
|
cached.lastAccess = Date.now();
|
|
78
83
|
return cached.doc;
|
|
79
84
|
}
|
|
80
|
-
const
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
85
|
+
const inFlight = _loadLocks.get(docId);
|
|
86
|
+
if (inFlight)
|
|
87
|
+
return inFlight;
|
|
88
|
+
const load = (async () => {
|
|
89
|
+
// Re-check the cache: a concurrent writer (or loader) may have populated it
|
|
90
|
+
// between our miss above and acquiring this load slot.
|
|
91
|
+
const reCached = _cache.get(docId);
|
|
92
|
+
if (reCached) {
|
|
93
|
+
reCached.lastAccess = Date.now();
|
|
94
|
+
return reCached.doc;
|
|
95
|
+
}
|
|
96
|
+
const doc = new Y.Doc();
|
|
97
|
+
const stored = await loadYDocState(docId);
|
|
98
|
+
if (stored && stored.length > 0) {
|
|
99
|
+
Y.applyUpdate(doc, stored);
|
|
100
|
+
}
|
|
101
|
+
evictIfNeeded();
|
|
102
|
+
_cache.set(docId, { doc, lastAccess: Date.now() });
|
|
103
|
+
return doc;
|
|
104
|
+
})();
|
|
105
|
+
_loadLocks.set(docId, load);
|
|
106
|
+
try {
|
|
107
|
+
return await load;
|
|
108
|
+
}
|
|
109
|
+
finally {
|
|
110
|
+
_loadLocks.delete(docId);
|
|
84
111
|
}
|
|
85
|
-
evictIfNeeded();
|
|
86
|
-
_cache.set(docId, { doc, lastAccess: Date.now() });
|
|
87
|
-
return doc;
|
|
88
112
|
}
|
|
89
113
|
/**
|
|
90
114
|
* Apply a binary Yjs update (from a client) to a document.
|
|
@@ -200,7 +224,10 @@ export async function applyJson(docId, newJson, fieldName = "data", type = "map"
|
|
|
200
224
|
const update = applyJsonDiff(doc, fieldName, newJson, "server");
|
|
201
225
|
if (update.length === 0)
|
|
202
226
|
return;
|
|
203
|
-
|
|
227
|
+
// Snapshot the doc's actual post-merge state, not the caller-supplied
|
|
228
|
+
// `newJson` — persistMergedState may re-apply newer DB state to resolve
|
|
229
|
+
// concurrent writes, so `newJson` can be stale. Matches applyPatchOps.
|
|
230
|
+
await persistMergedState(docId, doc, () => JSON.stringify(yDocToJson(doc, fieldName)));
|
|
204
231
|
emitCollabUpdate(docId, uint8ArrayToBase64(update), requestSource);
|
|
205
232
|
});
|
|
206
233
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ydoc-manager.js","sourceRoot":"","sources":["../../src/collab/ydoc-manager.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,CAAC,MAAM,KAAK,CAAC;AACzB,OAAO,EACL,cAAc,EACd,aAAa,EACb,aAAa,EACb,gBAAgB,GACjB,MAAM,cAAc,CAAC;AACtB,OAAO,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AACrE,OAAO,EAAE,sBAAsB,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;AAC3E,OAAO,EACL,aAAa,EACb,cAAc,EACd,UAAU,EACV,gBAAgB,GAEjB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAChD,OAAO,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AAElD,MAAM,aAAa,GAAG,SAAS,CAAC;AAChC,MAAM,SAAS,GAAG,EAAE,CAAC;AAOrB,MAAM,MAAM,GAAG,IAAI,GAAG,EAAsB,CAAC;AAC7C,MAAM,WAAW,GAAG,IAAI,GAAG,EAAyB,CAAC;AAErD,SAAS,aAAa;IACpB,IAAI,MAAM,CAAC,IAAI,IAAI,SAAS;QAAE,OAAO;IACrC,sCAAsC;IACtC,IAAI,MAAM,GAAkB,IAAI,CAAC;IACjC,IAAI,UAAU,GAAG,QAAQ,CAAC;IAC1B,KAAK,MAAM,CAAC,EAAE,EAAE,KAAK,CAAC,IAAI,MAAM,EAAE,CAAC;QACjC,IAAI,KAAK,CAAC,UAAU,GAAG,UAAU,EAAE,CAAC;YAClC,UAAU,GAAG,KAAK,CAAC,UAAU,CAAC;YAC9B,MAAM,GAAG,EAAE,CAAC;QACd,CAAC;IACH,CAAC;IACD,IAAI,MAAM,EAAE,CAAC;QACX,MAAM,KAAK,GAAG,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QACjC,KAAK,EAAE,GAAG,CAAC,OAAO,EAAE,CAAC;QACrB,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IACxB,CAAC;AACH,CAAC;AAED,KAAK,UAAU,gBAAgB,CAC7B,KAAa,EACb,EAAoB;IAEpB,MAAM,QAAQ,GAAG,WAAW,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;IAC7D,IAAI,OAAoB,CAAC;IACzB,MAAM,OAAO,GAAG,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,EAAE;QAC5C,OAAO,GAAG,OAAO,CAAC;IACpB,CAAC,CAAC,CAAC;IACH,MAAM,OAAO,GAAG,QAAQ,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,CAAC;IAC7D,WAAW,CAAC,GAAG,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;IAEhC,MAAM,QAAQ,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;IAC/B,IAAI,CAAC;QACH,OAAO,MAAM,EAAE,EAAE,CAAC;IACpB,CAAC;YAAS,CAAC;QACT,OAAO,EAAE,CAAC;QACV,IAAI,WAAW,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,OAAO,EAAE,CAAC;YACvC,WAAW,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QAC5B,CAAC;IACH,CAAC;AACH,CAAC;AAED,KAAK,UAAU,gBAAgB,CAAC,KAAa,EAAE,GAAU;IACvD,MAAM,MAAM,GAAG,MAAM,aAAa,CAAC,KAAK,CAAC,CAAC;IAC1C,IAAI,MAAM,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAChC,CAAC,CAAC,WAAW,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;IAC7B,CAAC;AACH,CAAC;AAED,KAAK,UAAU,kBAAkB,CAC/B,KAAa,EACb,GAAU,EACV,eAA6B;IAE7B,KAAK,IAAI,OAAO,GAAG,CAAC,EAAE,OAAO,GAAG,CAAC,EAAE,OAAO,EAAE,EAAE,CAAC;QAC7C,MAAM,MAAM,GAAG,MAAM,cAAc,CAAC,KAAK,CAAC,CAAC;QAC3C,IAAI,MAAM,EAAE,KAAK,IAAI,MAAM,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC7C,CAAC,CAAC,WAAW,CAAC,GAAG,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC;QACnC,CAAC;QAED,MAAM,KAAK,GAAG,MAAM,gBAAgB,CAClC,KAAK,EACL,CAAC,CAAC,mBAAmB,CAAC,GAAG,CAAC,EAC1B,eAAe,EAAE,EACjB,MAAM,EAAE,OAAO,IAAI,IAAI,CACxB,CAAC;QACF,IAAI,KAAK;YAAE,OAAO;IACpB,CAAC;IAED,MAAM,gBAAgB,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;IACnC,MAAM,aAAa,CAAC,KAAK,EAAE,CAAC,CAAC,mBAAmB,CAAC,GAAG,CAAC,EAAE,eAAe,EAAE,CAAC,CAAC;AAC5E,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,MAAM,CAAC,KAAa;IACxC,MAAM,MAAM,GAAG,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;IACjC,IAAI,MAAM,EAAE,CAAC;QACX,MAAM,CAAC,UAAU,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QAC/B,OAAO,MAAM,CAAC,GAAG,CAAC;IACpB,CAAC;IAED,MAAM,GAAG,GAAG,IAAI,CAAC,CAAC,GAAG,EAAE,CAAC;IACxB,MAAM,MAAM,GAAG,MAAM,aAAa,CAAC,KAAK,CAAC,CAAC;IAC1C,IAAI,MAAM,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAChC,CAAC,CAAC,WAAW,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;IAC7B,CAAC;IAED,aAAa,EAAE,CAAC;IAChB,MAAM,CAAC,GAAG,CAAC,KAAK,EAAE,EAAE,GAAG,EAAE,UAAU,EAAE,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;IACnD,OAAO,GAAG,CAAC;AACb,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,WAAW,CAC/B,KAAa,EACb,MAAkB,EAClB,aAAsB;IAEtB,OAAO,gBAAgB,CAAC,KAAK,EAAE,KAAK,IAAI,EAAE;QACxC,MAAM,GAAG,GAAG,MAAM,MAAM,CAAC,KAAK,CAAC,CAAC;QAChC,MAAM,gBAAgB,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;QACnC,CAAC,CAAC,WAAW,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;QAE3B,MAAM,kBAAkB,CAAC,KAAK,EAAE,GAAG,EAAE,GAAG,EAAE,CACxC,GAAG,CAAC,OAAO,CAAC,aAAa,CAAC,CAAC,QAAQ,EAAE,CACtC,CAAC;QAEF,gBAAgB,CAAC,KAAK,EAAE,kBAAkB,CAAC,MAAM,CAAC,EAAE,aAAa,CAAC,CAAC;IACrE,CAAC,CAAC,CAAC;AACL,CAAC;AAED;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,SAAS,CAC7B,KAAa,EACb,OAAe,EACf,YAAoB,aAAa,EACjC,aAAsB;IAEtB,OAAO,gBAAgB,CAAC,KAAK,EAAE,KAAK,IAAI,EAAE;QACxC,MAAM,GAAG,GAAG,MAAM,MAAM,CAAC,KAAK,CAAC,CAAC;QAChC,MAAM,gBAAgB,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;QACnC,MAAM,MAAM,GAAG,eAAe,CAAC,GAAG,EAAE,SAAS,EAAE,OAAO,EAAE,QAAQ,CAAC,CAAC;QAElE,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACxB,OAAO,GAAG,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,QAAQ,EAAE,CAAC;QAC3C,CAAC;QAED,MAAM,kBAAkB,CAAC,KAAK,EAAE,GAAG,EAAE,GAAG,EAAE,CACxC,GAAG,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,QAAQ,EAAE,CAClC,CAAC;QAEF,gBAAgB,CAAC,KAAK,EAAE,kBAAkB,CAAC,MAAM,CAAC,EAAE,aAAa,CAAC,CAAC;QACnE,OAAO,GAAG,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,QAAQ,EAAE,CAAC;IAC3C,CAAC,CAAC,CAAC;AACL,CAAC;AAED;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,gBAAgB,CACpC,KAAa,EACb,IAAY,EACZ,OAAe,EACf,aAAsB;IAEtB,OAAO,gBAAgB,CAAC,KAAK,EAAE,KAAK,IAAI,EAAE;QACxC,MAAM,GAAG,GAAG,MAAM,MAAM,CAAC,KAAK,CAAC,CAAC;QAChC,MAAM,gBAAgB,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;QACnC,MAAM,QAAQ,GAAG,GAAG,CAAC,cAAc,CAAC,SAAS,CAAC,CAAC;QAE/C,iDAAiD;QACjD,IAAI,MAAM,GAAe,IAAI,UAAU,CAAC,CAAC,CAAC,CAAC;QAC3C,MAAM,OAAO,GAAG,CAAC,CAAa,EAAE,EAAE;YAChC,MAAM,GAAG,CAAC,CAAC;QACb,CAAC,CAAC;QACF,GAAG,CAAC,EAAE,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;QAE1B,IAAI,KAAK,GAAG,KAAK,CAAC;QAClB,GAAG,CAAC,QAAQ,CAAC,GAAG,EAAE;YAChB,KAAK,GAAG,sBAAsB,CAAC,QAAQ,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC;QAC1D,CAAC,EAAE,OAAO,CAAC,CAAC;QAEZ,GAAG,CAAC,GAAG,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;QAE3B,IAAI,CAAC,KAAK,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAClC,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,UAAU,CAAC,CAAC,CAAC,EAAE,CAAC;QACrD,CAAC;QAED,MAAM,kBAAkB,CAAC,KAAK,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC,mBAAmB,CAAC,QAAQ,CAAC,CAAC,CAAC;QAC1E,gBAAgB,CAAC,KAAK,EAAE,kBAAkB,CAAC,MAAM,CAAC,EAAE,aAAa,CAAC,CAAC;QAEnE,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;IACjC,CAAC,CAAC,CAAC;AACL,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,OAAO,CAC3B,KAAa,EACb,YAAoB,aAAa;IAEjC,MAAM,GAAG,GAAG,MAAM,MAAM,CAAC,KAAK,CAAC,CAAC;IAChC,MAAM,gBAAgB,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;IACnC,OAAO,GAAG,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,QAAQ,EAAE,CAAC;AAC3C,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,QAAQ,CAAC,KAAa;IAC1C,MAAM,GAAG,GAAG,MAAM,MAAM,CAAC,KAAK,CAAC,CAAC;IAChC,MAAM,gBAAgB,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;IACnC,OAAO,CAAC,CAAC,mBAAmB,CAAC,GAAG,CAAC,CAAC;AACpC,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY,CAChC,KAAa,EACb,iBAA6B;IAE7B,MAAM,GAAG,GAAG,MAAM,MAAM,CAAC,KAAK,CAAC,CAAC;IAChC,MAAM,gBAAgB,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;IACnC,OAAO,CAAC,CAAC,mBAAmB,CAAC,GAAG,EAAE,iBAAiB,CAAC,CAAC;AACvD,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY,CAChC,KAAa,EACb,IAAY,EACZ,YAAoB,aAAa;IAEjC,OAAO,gBAAgB,CAAC,KAAK,EAAE,KAAK,IAAI,EAAE;QACxC,MAAM,QAAQ,GAAG,MAAM,aAAa,CAAC,KAAK,CAAC,CAAC;QAC5C,IAAI,QAAQ,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC;YAAE,OAAO,CAAC,iBAAiB;QAE9D,MAAM,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG,gBAAgB,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;QACzD,MAAM,aAAa,CAAC,KAAK,EAAE,KAAK,EAAE,IAAI,CAAC,CAAC;QAExC,gBAAgB;QAChB,aAAa,EAAE,CAAC;QAChB,MAAM,CAAC,GAAG,CAAC,KAAK,EAAE,EAAE,GAAG,EAAE,UAAU,EAAE,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;IACrD,CAAC,CAAC,CAAC;AACL,CAAC;AAED,uEAAuE;AAEvE;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,SAAS,CAC7B,KAAa,EACb,OAAY,EACZ,YAAoB,MAAM,EAC1B,OAAwB,KAAK,EAC7B,aAAsB;IAEtB,OAAO,gBAAgB,CAAC,KAAK,EAAE,KAAK,IAAI,EAAE;QACxC,MAAM,GAAG,GAAG,MAAM,MAAM,CAAC,KAAK,CAAC,CAAC;QAChC,MAAM,gBAAgB,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;QACnC,MAAM,MAAM,GAAG,aAAa,CAAC,GAAG,EAAE,SAAS,EAAE,OAAO,EAAE,QAAQ,CAAC,CAAC;QAEhE,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO;QAEhC,MAAM,kBAAkB,CAAC,KAAK,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC;QAEpE,gBAAgB,CAAC,KAAK,EAAE,kBAAkB,CAAC,MAAM,CAAC,EAAE,aAAa,CAAC,CAAC;IACrE,CAAC,CAAC,CAAC;AACL,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CACjC,KAAa,EACb,GAAc,EACd,YAAoB,MAAM,EAC1B,aAAsB;IAEtB,OAAO,gBAAgB,CAAC,KAAK,EAAE,KAAK,IAAI,EAAE;QACxC,MAAM,GAAG,GAAG,MAAM,MAAM,CAAC,KAAK,CAAC,CAAC;QAChC,MAAM,gBAAgB,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;QACnC,MAAM,MAAM,GAAG,cAAc,CAAC,GAAG,EAAE,SAAS,EAAE,GAAG,EAAE,QAAQ,CAAC,CAAC;QAE7D,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO;QAEhC,MAAM,kBAAkB,CAAC,KAAK,EAAE,GAAG,EAAE,GAAG,EAAE,CACxC,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC,CAC3C,CAAC;QAEF,gBAAgB,CAAC,KAAK,EAAE,kBAAkB,CAAC,MAAM,CAAC,EAAE,aAAa,CAAC,CAAC;IACrE,CAAC,CAAC,CAAC;AACL,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,OAAO,CAC3B,KAAa,EACb,YAAoB,MAAM;IAE1B,MAAM,GAAG,GAAG,MAAM,MAAM,CAAC,KAAK,CAAC,CAAC;IAChC,MAAM,gBAAgB,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;IACnC,OAAO,UAAU,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC;AACpC,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY,CAChC,KAAa,EACb,IAAS,EACT,YAAoB,MAAM,EAC1B,OAAwB,KAAK;IAE7B,OAAO,gBAAgB,CAAC,KAAK,EAAE,KAAK,IAAI,EAAE;QACxC,MAAM,QAAQ,GAAG,MAAM,aAAa,CAAC,KAAK,CAAC,CAAC;QAC5C,IAAI,QAAQ,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC;YAAE,OAAO,CAAC,iBAAiB;QAE9D,MAAM,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG,gBAAgB,CAAC,SAAS,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;QAC/D,MAAM,aAAa,CAAC,KAAK,EAAE,KAAK,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC;QAExD,gBAAgB;QAChB,aAAa,EAAE,CAAC;QAChB,MAAM,CAAC,GAAG,CAAC,KAAK,EAAE,EAAE,GAAG,EAAE,UAAU,EAAE,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;IACrD,CAAC,CAAC,CAAC;AACL,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,UAAU,CAAC,KAAa;IACtC,MAAM,KAAK,GAAG,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;IAChC,IAAI,KAAK,EAAE,CAAC;QACV,KAAK,CAAC,GAAG,CAAC,OAAO,EAAE,CAAC;QACpB,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IACvB,CAAC;AACH,CAAC","sourcesContent":["/**\n * Server-side Yjs document manager with LRU caching and SQL persistence.\n */\n\nimport * as Y from \"yjs\";\nimport {\n loadYDocRecord,\n loadYDocState,\n saveYDocState,\n trySaveYDocState,\n} from \"./storage.js\";\nimport { applyTextToYDoc, initYDocWithText } from \"./text-to-yjs.js\";\nimport { searchAndReplaceInYXml, extractTextFromYXml } from \"./xml-ops.js\";\nimport {\n applyJsonDiff,\n applyJsonPatch,\n yDocToJson,\n initYDocWithJson,\n type PatchOp,\n} from \"./json-to-yjs.js\";\nimport { emitCollabUpdate } from \"./emitter.js\";\nimport { uint8ArrayToBase64 } from \"./storage.js\";\n\nconst DEFAULT_FIELD = \"content\";\nconst MAX_CACHE = 50;\n\ninterface CacheEntry {\n doc: Y.Doc;\n lastAccess: number;\n}\n\nconst _cache = new Map<string, CacheEntry>();\nconst _writeLocks = new Map<string, Promise<void>>();\n\nfunction evictIfNeeded(): void {\n if (_cache.size <= MAX_CACHE) return;\n // Evict least-recently-accessed entry\n let oldest: string | null = null;\n let oldestTime = Infinity;\n for (const [id, entry] of _cache) {\n if (entry.lastAccess < oldestTime) {\n oldestTime = entry.lastAccess;\n oldest = id;\n }\n }\n if (oldest) {\n const entry = _cache.get(oldest);\n entry?.doc.destroy();\n _cache.delete(oldest);\n }\n}\n\nasync function withDocWriteLock<T>(\n docId: string,\n fn: () => Promise<T>,\n): Promise<T> {\n const previous = _writeLocks.get(docId) ?? Promise.resolve();\n let release!: () => void;\n const current = new Promise<void>((resolve) => {\n release = resolve;\n });\n const chained = previous.catch(() => {}).then(() => current);\n _writeLocks.set(docId, chained);\n\n await previous.catch(() => {});\n try {\n return await fn();\n } finally {\n release();\n if (_writeLocks.get(docId) === chained) {\n _writeLocks.delete(docId);\n }\n }\n}\n\nasync function applyStoredState(docId: string, doc: Y.Doc): Promise<void> {\n const stored = await loadYDocState(docId);\n if (stored && stored.length > 0) {\n Y.applyUpdate(doc, stored);\n }\n}\n\nasync function persistMergedState(\n docId: string,\n doc: Y.Doc,\n getTextSnapshot: () => string,\n): Promise<void> {\n for (let attempt = 0; attempt < 5; attempt++) {\n const latest = await loadYDocRecord(docId);\n if (latest?.state && latest.state.length > 0) {\n Y.applyUpdate(doc, latest.state);\n }\n\n const saved = await trySaveYDocState(\n docId,\n Y.encodeStateAsUpdate(doc),\n getTextSnapshot(),\n latest?.version ?? null,\n );\n if (saved) return;\n }\n\n await applyStoredState(docId, doc);\n await saveYDocState(docId, Y.encodeStateAsUpdate(doc), getTextSnapshot());\n}\n\n/**\n * Get or load a Yjs document by ID. Creates a new empty doc if none exists.\n */\nexport async function getDoc(docId: string): Promise<Y.Doc> {\n const cached = _cache.get(docId);\n if (cached) {\n cached.lastAccess = Date.now();\n return cached.doc;\n }\n\n const doc = new Y.Doc();\n const stored = await loadYDocState(docId);\n if (stored && stored.length > 0) {\n Y.applyUpdate(doc, stored);\n }\n\n evictIfNeeded();\n _cache.set(docId, { doc, lastAccess: Date.now() });\n return doc;\n}\n\n/**\n * Apply a binary Yjs update (from a client) to a document.\n * Persists the result and emits a change event.\n */\nexport async function applyUpdate(\n docId: string,\n update: Uint8Array,\n requestSource?: string,\n): Promise<void> {\n return withDocWriteLock(docId, async () => {\n const doc = await getDoc(docId);\n await applyStoredState(docId, doc);\n Y.applyUpdate(doc, update);\n\n await persistMergedState(docId, doc, () =>\n doc.getText(DEFAULT_FIELD).toString(),\n );\n\n emitCollabUpdate(docId, uint8ArrayToBase64(update), requestSource);\n });\n}\n\n/**\n * Apply a text change to a document. Computes the minimal diff and\n * converts it to Yjs operations.\n *\n * Returns the text snapshot after the update.\n */\nexport async function applyText(\n docId: string,\n newText: string,\n fieldName: string = DEFAULT_FIELD,\n requestSource?: string,\n): Promise<string> {\n return withDocWriteLock(docId, async () => {\n const doc = await getDoc(docId);\n await applyStoredState(docId, doc);\n const update = applyTextToYDoc(doc, fieldName, newText, \"server\");\n\n if (update.length === 0) {\n return doc.getText(fieldName).toString();\n }\n\n await persistMergedState(docId, doc, () =>\n doc.getText(fieldName).toString(),\n );\n\n emitCollabUpdate(docId, uint8ArrayToBase64(update), requestSource);\n return doc.getText(fieldName).toString();\n });\n}\n\n/**\n * Search-and-replace text within a Y.XmlFragment (ProseMirror tree).\n * Produces minimal Yjs operations for cursor-preserving updates.\n *\n * Returns whether the text was found and the binary update.\n */\nexport async function searchAndReplace(\n docId: string,\n find: string,\n replace: string,\n requestSource?: string,\n): Promise<{ found: boolean; update: Uint8Array }> {\n return withDocWriteLock(docId, async () => {\n const doc = await getDoc(docId);\n await applyStoredState(docId, doc);\n const fragment = doc.getXmlFragment(\"default\");\n\n // Capture the update produced by the transaction\n let update: Uint8Array = new Uint8Array(0);\n const handler = (u: Uint8Array) => {\n update = u;\n };\n doc.on(\"update\", handler);\n\n let found = false;\n doc.transact(() => {\n found = searchAndReplaceInYXml(fragment, find, replace);\n }, \"agent\");\n\n doc.off(\"update\", handler);\n\n if (!found || update.length === 0) {\n return { found: false, update: new Uint8Array(0) };\n }\n\n await persistMergedState(docId, doc, () => extractTextFromYXml(fragment));\n emitCollabUpdate(docId, uint8ArrayToBase64(update), requestSource);\n\n return { found: true, update };\n });\n}\n\n/**\n * Get the current text content of a document field.\n */\nexport async function getText(\n docId: string,\n fieldName: string = DEFAULT_FIELD,\n): Promise<string> {\n const doc = await getDoc(docId);\n await applyStoredState(docId, doc);\n return doc.getText(fieldName).toString();\n}\n\n/**\n * Get the full document state as a Uint8Array.\n */\nexport async function getState(docId: string): Promise<Uint8Array> {\n const doc = await getDoc(docId);\n await applyStoredState(docId, doc);\n return Y.encodeStateAsUpdate(doc);\n}\n\n/**\n * Get an incremental update relative to a client's state vector.\n */\nexport async function getIncUpdate(\n docId: string,\n clientStateVector: Uint8Array,\n): Promise<Uint8Array> {\n const doc = await getDoc(docId);\n await applyStoredState(docId, doc);\n return Y.encodeStateAsUpdate(doc, clientStateVector);\n}\n\n/**\n * Seed a document from existing text content (for migration).\n * Only seeds if no collab state exists yet.\n */\nexport async function seedFromText(\n docId: string,\n text: string,\n fieldName: string = DEFAULT_FIELD,\n): Promise<void> {\n return withDocWriteLock(docId, async () => {\n const existing = await loadYDocState(docId);\n if (existing && existing.length > 0) return; // Already seeded\n\n const { doc, state } = initYDocWithText(fieldName, text);\n await saveYDocState(docId, state, text);\n\n // Cache the doc\n evictIfNeeded();\n _cache.set(docId, { doc, lastAccess: Date.now() });\n });\n}\n\n// ─── Structured JSON Operations ─────────────────────────────────────\n\n/**\n * Apply a full JSON update to a document. Computes the minimal diff\n * and converts it to Yjs operations on Y.Map/Y.Array.\n */\nexport async function applyJson(\n docId: string,\n newJson: any,\n fieldName: string = \"data\",\n type: \"map\" | \"array\" = \"map\",\n requestSource?: string,\n): Promise<void> {\n return withDocWriteLock(docId, async () => {\n const doc = await getDoc(docId);\n await applyStoredState(docId, doc);\n const update = applyJsonDiff(doc, fieldName, newJson, \"server\");\n\n if (update.length === 0) return;\n\n await persistMergedState(docId, doc, () => JSON.stringify(newJson));\n\n emitCollabUpdate(docId, uint8ArrayToBase64(update), requestSource);\n });\n}\n\n/**\n * Apply surgical JSON patch operations to a document.\n */\nexport async function applyPatchOps(\n docId: string,\n ops: PatchOp[],\n fieldName: string = \"data\",\n requestSource?: string,\n): Promise<void> {\n return withDocWriteLock(docId, async () => {\n const doc = await getDoc(docId);\n await applyStoredState(docId, doc);\n const update = applyJsonPatch(doc, fieldName, ops, \"server\");\n\n if (update.length === 0) return;\n\n await persistMergedState(docId, doc, () =>\n JSON.stringify(yDocToJson(doc, fieldName)),\n );\n\n emitCollabUpdate(docId, uint8ArrayToBase64(update), requestSource);\n });\n}\n\n/**\n * Get the current JSON state of a document field.\n */\nexport async function getJson(\n docId: string,\n fieldName: string = \"data\",\n): Promise<any> {\n const doc = await getDoc(docId);\n await applyStoredState(docId, doc);\n return yDocToJson(doc, fieldName);\n}\n\n/**\n * Seed a document from existing JSON content (for migration).\n * Only seeds if no collab state exists yet.\n */\nexport async function seedFromJson(\n docId: string,\n json: any,\n fieldName: string = \"data\",\n type: \"map\" | \"array\" = \"map\",\n): Promise<void> {\n return withDocWriteLock(docId, async () => {\n const existing = await loadYDocState(docId);\n if (existing && existing.length > 0) return; // Already seeded\n\n const { doc, state } = initYDocWithJson(fieldName, json, type);\n await saveYDocState(docId, state, JSON.stringify(json));\n\n // Cache the doc\n evictIfNeeded();\n _cache.set(docId, { doc, lastAccess: Date.now() });\n });\n}\n\n/**\n * Release a document from the in-memory cache.\n */\nexport function releaseDoc(docId: string): void {\n const entry = _cache.get(docId);\n if (entry) {\n entry.doc.destroy();\n _cache.delete(docId);\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"ydoc-manager.js","sourceRoot":"","sources":["../../src/collab/ydoc-manager.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Server-side Yjs document manager with LRU caching and SQL persistence.\n */\n\nimport * as Y from \"yjs\";\nimport {\n loadYDocRecord,\n loadYDocState,\n saveYDocState,\n trySaveYDocState,\n} from \"./storage.js\";\nimport { applyTextToYDoc, initYDocWithText } from \"./text-to-yjs.js\";\nimport { searchAndReplaceInYXml, extractTextFromYXml } from \"./xml-ops.js\";\nimport {\n applyJsonDiff,\n applyJsonPatch,\n yDocToJson,\n initYDocWithJson,\n type PatchOp,\n} from \"./json-to-yjs.js\";\nimport { emitCollabUpdate } from \"./emitter.js\";\nimport { uint8ArrayToBase64 } from \"./storage.js\";\n\nconst DEFAULT_FIELD = \"content\";\nconst MAX_CACHE = 50;\n\ninterface CacheEntry {\n doc: Y.Doc;\n lastAccess: number;\n}\n\nconst _cache = new Map<string, CacheEntry>();\nconst _writeLocks = new Map<string, Promise<void>>();\n// Coalesces concurrent cache-miss loads for the same docId. Without this, two\n// simultaneous getDoc() callers both miss the cache, both build a Y.Doc and\n// apply stored state, and the second _cache.set silently orphans the first\n// doc (a memory leak that grows with concurrent read traffic).\nconst _loadLocks = new Map<string, Promise<Y.Doc>>();\n\nfunction evictIfNeeded(): void {\n if (_cache.size <= MAX_CACHE) return;\n // Evict least-recently-accessed entry\n let oldest: string | null = null;\n let oldestTime = Infinity;\n for (const [id, entry] of _cache) {\n if (entry.lastAccess < oldestTime) {\n oldestTime = entry.lastAccess;\n oldest = id;\n }\n }\n if (oldest) {\n const entry = _cache.get(oldest);\n entry?.doc.destroy();\n _cache.delete(oldest);\n }\n}\n\nasync function withDocWriteLock<T>(\n docId: string,\n fn: () => Promise<T>,\n): Promise<T> {\n const previous = _writeLocks.get(docId) ?? Promise.resolve();\n let release!: () => void;\n const current = new Promise<void>((resolve) => {\n release = resolve;\n });\n const chained = previous.catch(() => {}).then(() => current);\n _writeLocks.set(docId, chained);\n\n await previous.catch(() => {});\n try {\n return await fn();\n } finally {\n release();\n if (_writeLocks.get(docId) === chained) {\n _writeLocks.delete(docId);\n }\n }\n}\n\nasync function applyStoredState(docId: string, doc: Y.Doc): Promise<void> {\n const stored = await loadYDocState(docId);\n if (stored && stored.length > 0) {\n Y.applyUpdate(doc, stored);\n }\n}\n\nasync function persistMergedState(\n docId: string,\n doc: Y.Doc,\n getTextSnapshot: () => string,\n): Promise<void> {\n for (let attempt = 0; attempt < 5; attempt++) {\n const latest = await loadYDocRecord(docId);\n if (latest?.state && latest.state.length > 0) {\n Y.applyUpdate(doc, latest.state);\n }\n\n const saved = await trySaveYDocState(\n docId,\n Y.encodeStateAsUpdate(doc),\n getTextSnapshot(),\n latest?.version ?? null,\n );\n if (saved) return;\n }\n\n await applyStoredState(docId, doc);\n await saveYDocState(docId, Y.encodeStateAsUpdate(doc), getTextSnapshot());\n}\n\n/**\n * Get or load a Yjs document by ID. Creates a new empty doc if none exists.\n */\nexport async function getDoc(docId: string): Promise<Y.Doc> {\n const cached = _cache.get(docId);\n if (cached) {\n cached.lastAccess = Date.now();\n return cached.doc;\n }\n\n const inFlight = _loadLocks.get(docId);\n if (inFlight) return inFlight;\n\n const load = (async () => {\n // Re-check the cache: a concurrent writer (or loader) may have populated it\n // between our miss above and acquiring this load slot.\n const reCached = _cache.get(docId);\n if (reCached) {\n reCached.lastAccess = Date.now();\n return reCached.doc;\n }\n\n const doc = new Y.Doc();\n const stored = await loadYDocState(docId);\n if (stored && stored.length > 0) {\n Y.applyUpdate(doc, stored);\n }\n\n evictIfNeeded();\n _cache.set(docId, { doc, lastAccess: Date.now() });\n return doc;\n })();\n\n _loadLocks.set(docId, load);\n try {\n return await load;\n } finally {\n _loadLocks.delete(docId);\n }\n}\n\n/**\n * Apply a binary Yjs update (from a client) to a document.\n * Persists the result and emits a change event.\n */\nexport async function applyUpdate(\n docId: string,\n update: Uint8Array,\n requestSource?: string,\n): Promise<void> {\n return withDocWriteLock(docId, async () => {\n const doc = await getDoc(docId);\n await applyStoredState(docId, doc);\n Y.applyUpdate(doc, update);\n\n await persistMergedState(docId, doc, () =>\n doc.getText(DEFAULT_FIELD).toString(),\n );\n\n emitCollabUpdate(docId, uint8ArrayToBase64(update), requestSource);\n });\n}\n\n/**\n * Apply a text change to a document. Computes the minimal diff and\n * converts it to Yjs operations.\n *\n * Returns the text snapshot after the update.\n */\nexport async function applyText(\n docId: string,\n newText: string,\n fieldName: string = DEFAULT_FIELD,\n requestSource?: string,\n): Promise<string> {\n return withDocWriteLock(docId, async () => {\n const doc = await getDoc(docId);\n await applyStoredState(docId, doc);\n const update = applyTextToYDoc(doc, fieldName, newText, \"server\");\n\n if (update.length === 0) {\n return doc.getText(fieldName).toString();\n }\n\n await persistMergedState(docId, doc, () =>\n doc.getText(fieldName).toString(),\n );\n\n emitCollabUpdate(docId, uint8ArrayToBase64(update), requestSource);\n return doc.getText(fieldName).toString();\n });\n}\n\n/**\n * Search-and-replace text within a Y.XmlFragment (ProseMirror tree).\n * Produces minimal Yjs operations for cursor-preserving updates.\n *\n * Returns whether the text was found and the binary update.\n */\nexport async function searchAndReplace(\n docId: string,\n find: string,\n replace: string,\n requestSource?: string,\n): Promise<{ found: boolean; update: Uint8Array }> {\n return withDocWriteLock(docId, async () => {\n const doc = await getDoc(docId);\n await applyStoredState(docId, doc);\n const fragment = doc.getXmlFragment(\"default\");\n\n // Capture the update produced by the transaction\n let update: Uint8Array = new Uint8Array(0);\n const handler = (u: Uint8Array) => {\n update = u;\n };\n doc.on(\"update\", handler);\n\n let found = false;\n doc.transact(() => {\n found = searchAndReplaceInYXml(fragment, find, replace);\n }, \"agent\");\n\n doc.off(\"update\", handler);\n\n if (!found || update.length === 0) {\n return { found: false, update: new Uint8Array(0) };\n }\n\n await persistMergedState(docId, doc, () => extractTextFromYXml(fragment));\n emitCollabUpdate(docId, uint8ArrayToBase64(update), requestSource);\n\n return { found: true, update };\n });\n}\n\n/**\n * Get the current text content of a document field.\n */\nexport async function getText(\n docId: string,\n fieldName: string = DEFAULT_FIELD,\n): Promise<string> {\n const doc = await getDoc(docId);\n await applyStoredState(docId, doc);\n return doc.getText(fieldName).toString();\n}\n\n/**\n * Get the full document state as a Uint8Array.\n */\nexport async function getState(docId: string): Promise<Uint8Array> {\n const doc = await getDoc(docId);\n await applyStoredState(docId, doc);\n return Y.encodeStateAsUpdate(doc);\n}\n\n/**\n * Get an incremental update relative to a client's state vector.\n */\nexport async function getIncUpdate(\n docId: string,\n clientStateVector: Uint8Array,\n): Promise<Uint8Array> {\n const doc = await getDoc(docId);\n await applyStoredState(docId, doc);\n return Y.encodeStateAsUpdate(doc, clientStateVector);\n}\n\n/**\n * Seed a document from existing text content (for migration).\n * Only seeds if no collab state exists yet.\n */\nexport async function seedFromText(\n docId: string,\n text: string,\n fieldName: string = DEFAULT_FIELD,\n): Promise<void> {\n return withDocWriteLock(docId, async () => {\n const existing = await loadYDocState(docId);\n if (existing && existing.length > 0) return; // Already seeded\n\n const { doc, state } = initYDocWithText(fieldName, text);\n await saveYDocState(docId, state, text);\n\n // Cache the doc\n evictIfNeeded();\n _cache.set(docId, { doc, lastAccess: Date.now() });\n });\n}\n\n// ─── Structured JSON Operations ─────────────────────────────────────\n\n/**\n * Apply a full JSON update to a document. Computes the minimal diff\n * and converts it to Yjs operations on Y.Map/Y.Array.\n */\nexport async function applyJson(\n docId: string,\n newJson: any,\n fieldName: string = \"data\",\n type: \"map\" | \"array\" = \"map\",\n requestSource?: string,\n): Promise<void> {\n return withDocWriteLock(docId, async () => {\n const doc = await getDoc(docId);\n await applyStoredState(docId, doc);\n const update = applyJsonDiff(doc, fieldName, newJson, \"server\");\n\n if (update.length === 0) return;\n\n // Snapshot the doc's actual post-merge state, not the caller-supplied\n // `newJson` — persistMergedState may re-apply newer DB state to resolve\n // concurrent writes, so `newJson` can be stale. Matches applyPatchOps.\n await persistMergedState(docId, doc, () =>\n JSON.stringify(yDocToJson(doc, fieldName)),\n );\n\n emitCollabUpdate(docId, uint8ArrayToBase64(update), requestSource);\n });\n}\n\n/**\n * Apply surgical JSON patch operations to a document.\n */\nexport async function applyPatchOps(\n docId: string,\n ops: PatchOp[],\n fieldName: string = \"data\",\n requestSource?: string,\n): Promise<void> {\n return withDocWriteLock(docId, async () => {\n const doc = await getDoc(docId);\n await applyStoredState(docId, doc);\n const update = applyJsonPatch(doc, fieldName, ops, \"server\");\n\n if (update.length === 0) return;\n\n await persistMergedState(docId, doc, () =>\n JSON.stringify(yDocToJson(doc, fieldName)),\n );\n\n emitCollabUpdate(docId, uint8ArrayToBase64(update), requestSource);\n });\n}\n\n/**\n * Get the current JSON state of a document field.\n */\nexport async function getJson(\n docId: string,\n fieldName: string = \"data\",\n): Promise<any> {\n const doc = await getDoc(docId);\n await applyStoredState(docId, doc);\n return yDocToJson(doc, fieldName);\n}\n\n/**\n * Seed a document from existing JSON content (for migration).\n * Only seeds if no collab state exists yet.\n */\nexport async function seedFromJson(\n docId: string,\n json: any,\n fieldName: string = \"data\",\n type: \"map\" | \"array\" = \"map\",\n): Promise<void> {\n return withDocWriteLock(docId, async () => {\n const existing = await loadYDocState(docId);\n if (existing && existing.length > 0) return; // Already seeded\n\n const { doc, state } = initYDocWithJson(fieldName, json, type);\n await saveYDocState(docId, state, JSON.stringify(json));\n\n // Cache the doc\n evictIfNeeded();\n _cache.set(docId, { doc, lastAccess: Date.now() });\n });\n}\n\n/**\n * Release a document from the in-memory cache.\n */\nexport function releaseDoc(docId: string): void {\n const entry = _cache.get(docId);\n if (entry) {\n entry.doc.destroy();\n _cache.delete(docId);\n }\n}\n"]}
|
package/dist/deploy/build.js
CHANGED
|
@@ -1327,11 +1327,6 @@ export default bundle;
|
|
|
1327
1327
|
for (const mod of bareImports) {
|
|
1328
1328
|
const outFile = path.join(libsDir, `${mod.replace(/[/@]/g, "_")}.mjs`);
|
|
1329
1329
|
try {
|
|
1330
|
-
// Try resolving from both template dir and workspace root
|
|
1331
|
-
const nodePaths = [
|
|
1332
|
-
path.join(cwd, "node_modules"),
|
|
1333
|
-
path.resolve(cwd, "../../node_modules"),
|
|
1334
|
-
].filter((p) => fs.existsSync(p));
|
|
1335
1330
|
// Resolve the module — check workspace node_modules and pnpm store
|
|
1336
1331
|
let resolvedMod = mod;
|
|
1337
1332
|
const _require = createRequire(cwd + "/");
|