mirror of
https://github.com/mathuo/dockview
synced 2026-09-16 02:48:51 +00:00
feat(enterprise): split dockview-modules into published dockview-enterprise
Turn the enterprise tier on by making the feature-module package a separately-published, self-activating package, and decoupling it from the free `dockview` package. Package: - Rename dockview-modules -> dockview-enterprise (directory + manifest); drop `private`, set `sideEffects: true`, depend ONLY on `dockview` at an exact version, re-export it (`export * from 'dockview'`) so the package is a drop-in superset (mirrors ag-grid-enterprise -> ag-grid-community). - Repoint all source off `dockview-core` onto `dockview`; rollup now externalizes `dockview`. - Add LicenseModule to the Modules bundle and self-register on import (registerModules(Modules)) — importing the package activates the feature modules and the license watermark-unless-licensed check. Free dockview: - Remove `registerModules(Modules)` and the dockview-modules devDep + rollup bundling. `dockview` is now a thin re-export of `dockview-core`; the feature modules ship only via `dockview-enterprise`. Consumers/config: - Rename across nx.json, root scripts, tsconfig(s), sonar, jest configs (+ a new `^dockview$` mapper), vite, docusaurus, systemjs, playwright. - Rewire the e2e fixture to load dockview.js + self-registering dockview-enterprise.js. - Repoint the demo with a side-effect `import 'dockview-enterprise'`. Verified: core+dockview+react 1171/1171, enterprise 285/285, e2e green; enterprise bundle stamps the release date + externalizes dockview; the free dockview bundle no longer contains the enterprise modules. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
f03fda1827
commit
0c96bf2452
+1
-1
@@ -20,7 +20,7 @@ main document, so a popout there is not a genuine second window.)
|
||||
The fixture loads the UMD bundles from `dist/`, so build them first:
|
||||
|
||||
```bash
|
||||
yarn nx run-many -t build:bundle -p dockview-core dockview-modules
|
||||
yarn nx run-many -t build:bundle -p dockview-core dockview-enterprise
|
||||
yarn playwright install chromium # first time only
|
||||
yarn test:e2e
|
||||
```
|
||||
|
||||
+12
-17
@@ -28,25 +28,20 @@
|
||||
href="/packages/dockview-core/dist/styles/dockview.css"
|
||||
/>
|
||||
|
||||
<!-- Built UMD bundles. dockview-core exposes the global "dockview-core";
|
||||
dockview-modules expects it aliased as DockviewCore. -->
|
||||
<script src="/packages/dockview-core/dist/dockview-core.js"></script>
|
||||
<script>
|
||||
window.DockviewCore = window['dockview-core'];
|
||||
</script>
|
||||
<script src="/packages/dockview-modules/dist/dockview-modules.js"></script>
|
||||
<!-- Built UMD bundles. `dockview` (self-contained — bundles core in)
|
||||
exposes the global `dockview`; `dockview-enterprise` externalizes it
|
||||
and, when it loads, self-registers its feature modules + the license
|
||||
check into that same core registry. -->
|
||||
<script src="/packages/dockview/dist/dockview.js"></script>
|
||||
<script src="/packages/dockview-enterprise/dist/dockview-enterprise.js"></script>
|
||||
|
||||
<script>
|
||||
(function () {
|
||||
const core = window['dockview-core'];
|
||||
const modules = window['dockview-modules'];
|
||||
const lib = window['dockview'];
|
||||
|
||||
// Register the full module set plus the optional keyboard-docking
|
||||
// module so the harness can exercise cross-window keyboard work.
|
||||
core.registerModules([
|
||||
...modules.Modules,
|
||||
modules.KeyboardDockingModule,
|
||||
]);
|
||||
// The enterprise feature modules (incl. keyboard docking + the
|
||||
// license check) self-register when dockview-enterprise.js loads
|
||||
// above, so no explicit registerModules call is needed here.
|
||||
|
||||
const el = document.getElementById('app');
|
||||
const params = new URLSearchParams(location.search);
|
||||
@@ -60,7 +55,7 @@
|
||||
// to exercise the 2-D cross-row wrap reorder path).
|
||||
const theme =
|
||||
params.get('smooth') === '1'
|
||||
? { ...core.themeAbyss, tabAnimation: 'smooth' }
|
||||
? { ...lib.themeAbyss, tabAnimation: 'smooth' }
|
||||
: undefined;
|
||||
// `?pinned=separate-row` exercises the two-row pinned layout;
|
||||
// `?compact=1` opts into icon-only pinned tabs.
|
||||
@@ -68,7 +63,7 @@
|
||||
params.get('pinned') === 'separate-row'
|
||||
? 'separate-row'
|
||||
: 'inline';
|
||||
const dockview = new core.DockviewComponent(el, {
|
||||
const dockview = new lib.DockviewComponent(el, {
|
||||
keyboardNavigation: true,
|
||||
overflow,
|
||||
theme,
|
||||
|
||||
@@ -44,7 +44,7 @@
|
||||
"release": {
|
||||
"projects": [
|
||||
"dockview-core",
|
||||
"dockview-modules",
|
||||
"dockview-enterprise",
|
||||
"dockview",
|
||||
"dockview-vue",
|
||||
"dockview-react",
|
||||
|
||||
+2
-2
@@ -16,8 +16,8 @@
|
||||
"packages/*"
|
||||
],
|
||||
"scripts": {
|
||||
"build": "nx run-many -t build --projects=dockview-core,dockview-modules,dockview,dockview-vue,dockview-react,dockview-angular",
|
||||
"build:bundle": "nx run-many -t build:bundle --projects=dockview-core,dockview-modules,dockview,dockview-vue,dockview-react,dockview-angular",
|
||||
"build": "nx run-many -t build --projects=dockview-core,dockview-enterprise,dockview,dockview-vue,dockview-react,dockview-angular",
|
||||
"build:bundle": "nx run-many -t build:bundle --projects=dockview-core,dockview-enterprise,dockview,dockview-vue,dockview-react,dockview-angular",
|
||||
"clean": "nx run-many -t clean",
|
||||
"docs": "typedoc && node scripts/docs.mjs",
|
||||
"lint": "nx run-many -t lint",
|
||||
|
||||
@@ -13,14 +13,14 @@ const config: JestConfigWithTsJest = {
|
||||
'!<rootDir>/packages/dockview-angular/src/public-api.ts',
|
||||
],
|
||||
setupFilesAfterEnv: [
|
||||
'<rootDir>/packages/dockview-angular/src/__tests__/setup-jest.ts'
|
||||
'<rootDir>/packages/dockview-angular/src/__tests__/setup-jest.ts',
|
||||
],
|
||||
coveragePathIgnorePatterns: ['/node_modules/'],
|
||||
moduleNameMapper: {
|
||||
'^dockview$': '<rootDir>/packages/dockview/src/index.ts',
|
||||
'^dockview-core$': '<rootDir>/packages/dockview-core/src/index.ts',
|
||||
'^dockview-modules$':
|
||||
'<rootDir>/packages/dockview-modules/src/index.ts',
|
||||
'^dockview-enterprise$':
|
||||
'<rootDir>/packages/dockview-enterprise/src/index.ts',
|
||||
},
|
||||
modulePathIgnorePatterns: [
|
||||
'<rootDir>/packages/dockview-angular/src/__tests__/__mocks__',
|
||||
@@ -31,11 +31,9 @@ const config: JestConfigWithTsJest = {
|
||||
testEnvironment: 'jsdom',
|
||||
testMatch: [
|
||||
'<rootDir>/packages/dockview-angular/src/**/*.spec.ts',
|
||||
'<rootDir>/packages/dockview-angular/src/**/*.test.ts'
|
||||
],
|
||||
transformIgnorePatterns: [
|
||||
'node_modules/(?!(.*\\.mjs$|@angular|rxjs))'
|
||||
'<rootDir>/packages/dockview-angular/src/**/*.test.ts',
|
||||
],
|
||||
transformIgnorePatterns: ['node_modules/(?!(.*\\.mjs$|@angular|rxjs))'],
|
||||
transform: {
|
||||
'^.+\\.(ts|mjs|js|html)$': [
|
||||
'jest-preset-angular',
|
||||
|
||||
@@ -30,7 +30,7 @@ class TestContentPart implements IContentRenderer {
|
||||
/**
|
||||
* The free seam the `MultiRowTabsModule` consumes (PR-A): the tab-list element
|
||||
* exposed up through the group model + host, and the `relayoutGroup` host hook.
|
||||
* The module itself (wrap layout) is tested in `dockview-modules`.
|
||||
* The module itself (wrap layout) is tested in `dockview-enterprise`.
|
||||
*/
|
||||
describe('multi-row tabs seam', () => {
|
||||
function createComponent() {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# AGENTS.md - dockview-modules
|
||||
# AGENTS.md - dockview-enterprise
|
||||
|
||||
A separately-published home for a subset of dockview's feature modules. Depends
|
||||
on `dockview-core`; consumed by `dockview` (which registers these modules so the
|
||||
@@ -42,4 +42,4 @@ batteries-included entry point keeps its full feature set).
|
||||
|
||||
## Dependencies
|
||||
|
||||
- Depends on: `dockview-core` (build chain: `dockview-core` -> `dockview-modules` -> `dockview`)
|
||||
- Depends on: `dockview-core` (build chain: `dockview-core` -> `dockview-enterprise` -> `dockview`)
|
||||
@@ -0,0 +1,45 @@
|
||||
# AGENTS.md - dockview-enterprise
|
||||
|
||||
A separately-published home for a subset of dockview's feature modules. Depends
|
||||
on `dockview-core`; consumed by `dockview` (which registers these modules so the
|
||||
batteries-included entry point keeps its full feature set).
|
||||
|
||||
> Neutral alias — keep commercial/tier language out of this package, its code,
|
||||
> and commit messages.
|
||||
|
||||
## Modules hosted here
|
||||
|
||||
- `TabGroupChipsModule` (`tabGroupChipsService.ts`)
|
||||
- `ContextMenuModule` (`contextMenu.ts`)
|
||||
- `AdvancedDnDModule` (`advancedDnDService.ts`)
|
||||
- `AccessibilityModule` (`accessibilityService.ts`) — `dependsOn` AdvancedDnD
|
||||
(here) and LiveRegion (stays in core)
|
||||
|
||||
`src/index.ts` exports each module plus a `Modules` bundle array.
|
||||
|
||||
## How it fits the module system
|
||||
|
||||
- Core owns the contracts: the `ServiceCollection` slots and the `IFooService`
|
||||
/ `IFooHost` interfaces in `dockview-core` (`dockview/moduleContracts.ts`).
|
||||
Core code only ever touches `services.fooService?.` — never an implementation
|
||||
here. Option types also stay in core (`dockview/options.ts`).
|
||||
- These files import what they need from the `dockview-core` **main entry**
|
||||
(`'dockview-core'`); the few internals they require (`defineModule`, the
|
||||
contracts, `resolveMessages`, `findRelativeZIndexParent`, `IDragGhostSpec`,
|
||||
`LiveRegionModule`) are exported from core's public index. No `dist/` deep
|
||||
imports.
|
||||
- Registration is global: `dockview` calls `registerModules(Modules)` at import
|
||||
time. `DockviewComponent` appends globally-registered modules to its built-in
|
||||
set at construction.
|
||||
|
||||
## Build / Test
|
||||
|
||||
- `build` - tsc CJS + ESM (no CSS; styles live in core)
|
||||
- `build:bundle` - rollup; externalizes `dockview-core`
|
||||
- `test` - Jest (jsdom). `src/__tests__/registerModules.ts` registers `Modules`
|
||||
globally so a default `DockviewComponent` in tests has the full feature set;
|
||||
ResizeObserver/PointerEvent jsdom mocks are reused from core.
|
||||
|
||||
## Dependencies
|
||||
|
||||
- Depends on: `dockview-core` (build chain: `dockview-core` -> `dockview-enterprise` -> `dockview`)
|
||||
@@ -1,4 +1,4 @@
|
||||
# dockview-modules
|
||||
# dockview-enterprise
|
||||
|
||||
Separable feature modules for [dockview](https://github.com/mathuo/dockview).
|
||||
|
||||
@@ -10,7 +10,7 @@ feature set out of the box.
|
||||
```ts
|
||||
// dockview (the batteries-included entry) does this for you:
|
||||
import { registerModules } from 'dockview-core';
|
||||
import { Modules } from 'dockview-modules';
|
||||
import { Modules } from 'dockview-enterprise';
|
||||
|
||||
registerModules(Modules);
|
||||
```
|
||||
+12
-9
@@ -2,12 +2,12 @@ import { JestConfigWithTsJest } from 'ts-jest';
|
||||
|
||||
const config: JestConfigWithTsJest = {
|
||||
preset: 'ts-jest',
|
||||
roots: ['<rootDir>/packages/dockview-modules'],
|
||||
modulePaths: ['<rootDir>/packages/dockview-modules/src'],
|
||||
displayName: { name: 'dockview-modules', color: 'blue' },
|
||||
roots: ['<rootDir>/packages/dockview-enterprise'],
|
||||
modulePaths: ['<rootDir>/packages/dockview-enterprise/src'],
|
||||
displayName: { name: 'dockview-enterprise', color: 'blue' },
|
||||
rootDir: '../../',
|
||||
collectCoverageFrom: [
|
||||
'<rootDir>/packages/dockview-modules/src/**/*.{js,jsx,ts,tsx}',
|
||||
'<rootDir>/packages/dockview-enterprise/src/**/*.{js,jsx,ts,tsx}',
|
||||
],
|
||||
setupFiles: [
|
||||
// ResizeObserver / PointerEvent are not implemented in jsdom; reuse the
|
||||
@@ -17,18 +17,21 @@ const config: JestConfigWithTsJest = {
|
||||
],
|
||||
setupFilesAfterEnv: [
|
||||
'<rootDir>/jest-setup.ts',
|
||||
'<rootDir>/packages/dockview-modules/src/__tests__/registerModules.ts',
|
||||
'<rootDir>/packages/dockview-enterprise/src/__tests__/registerModules.ts',
|
||||
],
|
||||
coveragePathIgnorePatterns: ['/node_modules/'],
|
||||
moduleNameMapper: {
|
||||
'^dockview-core$': '<rootDir>/packages/dockview-core/src/index.ts',
|
||||
'^dockview-modules$':
|
||||
'<rootDir>/packages/dockview-modules/src/index.ts',
|
||||
// The enterprise source imports the base API from `dockview` (not
|
||||
// `dockview-core`), so map it to the dockview source too.
|
||||
'^dockview$': '<rootDir>/packages/dockview/src/index.ts',
|
||||
'^dockview-enterprise$':
|
||||
'<rootDir>/packages/dockview-enterprise/src/index.ts',
|
||||
},
|
||||
modulePathIgnorePatterns: [
|
||||
'<rootDir>/packages/dockview-modules/src/__tests__/registerModules.ts',
|
||||
'<rootDir>/packages/dockview-enterprise/src/__tests__/registerModules.ts',
|
||||
],
|
||||
coverageDirectory: '<rootDir>/packages/dockview-modules/coverage/',
|
||||
coverageDirectory: '<rootDir>/packages/dockview-enterprise/coverage/',
|
||||
// testResultsProcessor inherited from root config
|
||||
testEnvironment: 'jsdom',
|
||||
transform: {
|
||||
@@ -1,14 +1,13 @@
|
||||
{
|
||||
"name": "dockview-modules",
|
||||
"name": "dockview-enterprise",
|
||||
"version": "7.0.2",
|
||||
"private": true,
|
||||
"description": "Separable feature modules for dockview",
|
||||
"description": "Enterprise feature modules and licensing for dockview",
|
||||
"keywords": [
|
||||
"dockview",
|
||||
"layout",
|
||||
"layout manager",
|
||||
"docking",
|
||||
"modules"
|
||||
"enterprise"
|
||||
],
|
||||
"homepage": "https://github.com/mathuo/dockview",
|
||||
"bugs": {
|
||||
@@ -23,7 +22,7 @@
|
||||
"main": "./dist/package/main.cjs.js",
|
||||
"module": "./dist/package/main.esm.mjs",
|
||||
"types": "./dist/cjs/index.d.ts",
|
||||
"sideEffects": false,
|
||||
"sideEffects": true,
|
||||
"files": [
|
||||
"dist",
|
||||
"README.md"
|
||||
@@ -35,14 +34,14 @@
|
||||
"build": "npm run build:cjs && npm run build:esm",
|
||||
"clean": "rimraf dist/ .build/ .rollup.cache/",
|
||||
"rebuild": "npm run clean && npm run build",
|
||||
"test": "jest --selectProjects dockview-modules",
|
||||
"test:cov": "jest --selectProjects dockview-modules --coverage",
|
||||
"test": "jest --selectProjects dockview-enterprise",
|
||||
"test:cov": "jest --selectProjects dockview-enterprise --coverage",
|
||||
"lint": "eslint 'src/**/*.{ts,tsx,js,jsx}'",
|
||||
"lint:fix": "eslint 'src/**/*.{ts,tsx,js,jsx}' --fix",
|
||||
"format": "prettier --write 'src/**/*.{ts,tsx,js,jsx}'",
|
||||
"format:check": "prettier --check 'src/**/*.{ts,tsx,js,jsx}'"
|
||||
},
|
||||
"dependencies": {
|
||||
"dockview-core": "^7.0.2"
|
||||
"dockview": "7.0.2"
|
||||
}
|
||||
}
|
||||
+5
-6
@@ -48,10 +48,9 @@ function outputFile(format, isMinified) {
|
||||
return `${filename}.${ext}`;
|
||||
}
|
||||
|
||||
// dockview-core (and its deep internal paths) is a declared dependency and is
|
||||
// always externalized — the bundle ships only the module implementations.
|
||||
const isCoreExternal = (id) =>
|
||||
id === 'dockview-core' || id.startsWith('dockview-core/');
|
||||
// `dockview` (the free package, this package's sole base dependency) is always
|
||||
// externalized — the bundle ships only the enterprise module implementations.
|
||||
const isBaseExternal = (id) => id === 'dockview' || id.startsWith('dockview/');
|
||||
|
||||
function createBundle(format, options) {
|
||||
const { isMinified } = options;
|
||||
@@ -61,7 +60,7 @@ function createBundle(format, options) {
|
||||
file,
|
||||
format,
|
||||
sourcemap: isMinified && format === 'umd',
|
||||
globals: { 'dockview-core': 'DockviewCore' },
|
||||
globals: { dockview: 'dockview' },
|
||||
banner: [
|
||||
`/**`,
|
||||
` * ${name}`,
|
||||
@@ -94,7 +93,7 @@ function createBundle(format, options) {
|
||||
input,
|
||||
output,
|
||||
plugins,
|
||||
external: isCoreExternal,
|
||||
external: isBaseExternal,
|
||||
};
|
||||
}
|
||||
|
||||
+5
-5
@@ -1,8 +1,8 @@
|
||||
import { DockviewCompositeDisposable as CompositeDisposable } from 'dockview-core';
|
||||
import { DockviewGroupPanel } from 'dockview-core';
|
||||
import { DockviewKeybindings, KeyboardNavigationOptions } from 'dockview-core';
|
||||
import { defineModule } from 'dockview-core';
|
||||
import { IAccessibilityHost, IAccessibilityService } from 'dockview-core';
|
||||
import { DockviewCompositeDisposable as CompositeDisposable } from 'dockview';
|
||||
import { DockviewGroupPanel } from 'dockview';
|
||||
import { DockviewKeybindings, KeyboardNavigationOptions } from 'dockview';
|
||||
import { defineModule } from 'dockview';
|
||||
import { IAccessibilityHost, IAccessibilityService } from 'dockview';
|
||||
import {
|
||||
bindDocumentListeners,
|
||||
KEYBOARD_MOVE_ATTRIBUTE,
|
||||
+8
-11
@@ -1,20 +1,17 @@
|
||||
import { DockviewCompositeDisposable as CompositeDisposable } from 'dockview-core';
|
||||
import { DockviewGroupPanel } from 'dockview-core';
|
||||
import { IDockviewPanel } from 'dockview-core';
|
||||
import { EdgeGroupPosition } from 'dockview-core';
|
||||
import { AutoHideEdgeGroupOptions } from 'dockview-core';
|
||||
import { defineModule, EdgeGroupModule } from 'dockview-core';
|
||||
import { DockviewCompositeDisposable as CompositeDisposable } from 'dockview';
|
||||
import { DockviewGroupPanel } from 'dockview';
|
||||
import { IDockviewPanel } from 'dockview';
|
||||
import { EdgeGroupPosition } from 'dockview';
|
||||
import { AutoHideEdgeGroupOptions } from 'dockview';
|
||||
import { defineModule, EdgeGroupModule } from 'dockview';
|
||||
import {
|
||||
createCloseButton,
|
||||
createDismissableLayer,
|
||||
createPinButton,
|
||||
prefersReducedMotion,
|
||||
resolveOpaqueBackground,
|
||||
} from 'dockview-core';
|
||||
import {
|
||||
IAutoHideEdgeGroupHost,
|
||||
IAutoHideEdgeGroupService,
|
||||
} from 'dockview-core';
|
||||
} from 'dockview';
|
||||
import { IAutoHideEdgeGroupHost, IAutoHideEdgeGroupService } from 'dockview';
|
||||
|
||||
/** Height (px) of the title bar; the content/`always` overlay is inset below it
|
||||
* so nothing paints under the bar. The title bar's own height is set inline to
|
||||
+8
-8
@@ -1,15 +1,15 @@
|
||||
import { findRelativeZIndexParent } from 'dockview-core';
|
||||
import { DockviewGroupPanel } from 'dockview-core';
|
||||
import { IDockviewPanel } from 'dockview-core';
|
||||
import { findRelativeZIndexParent } from 'dockview';
|
||||
import { DockviewGroupPanel } from 'dockview';
|
||||
import { IDockviewPanel } from 'dockview';
|
||||
import {
|
||||
BuiltInChipContextMenuItem,
|
||||
ContextMenuItemConfig,
|
||||
ContextMenuItem,
|
||||
} from 'dockview-core';
|
||||
import { ITabGroup } from 'dockview-core';
|
||||
import { TabGroupColorPalette } from 'dockview-core';
|
||||
import { defineModule } from 'dockview-core';
|
||||
import { IContextMenuHost, IContextMenuService } from 'dockview-core';
|
||||
} from 'dockview';
|
||||
import { ITabGroup } from 'dockview';
|
||||
import { TabGroupColorPalette } from 'dockview';
|
||||
import { defineModule } from 'dockview';
|
||||
import { IContextMenuHost, IContextMenuService } from 'dockview';
|
||||
|
||||
function popoverZIndexFor(target: EventTarget | null): string | undefined {
|
||||
if (!(target instanceof HTMLElement)) {
|
||||
+5
-5
@@ -1,7 +1,7 @@
|
||||
import {
|
||||
DockviewCompositeDisposable as CompositeDisposable,
|
||||
DockviewIDisposable as IDisposable,
|
||||
} from 'dockview-core';
|
||||
} from 'dockview';
|
||||
import {
|
||||
DockviewGroupPanel,
|
||||
DockviewWillShowOverlayLocationEvent,
|
||||
@@ -9,10 +9,10 @@ import {
|
||||
PositionResolver,
|
||||
PositionResolverArgs,
|
||||
PositionResolverResult,
|
||||
} from 'dockview-core';
|
||||
import { defineModule } from 'dockview-core';
|
||||
import { IDropGuideHost, IDropGuideService } from 'dockview-core';
|
||||
import { AdvancedDnDModule } from 'dockview-core';
|
||||
} from 'dockview';
|
||||
import { defineModule } from 'dockview';
|
||||
import { IDropGuideHost, IDropGuideService } from 'dockview';
|
||||
import { AdvancedDnDModule } from 'dockview';
|
||||
|
||||
/** Size (px) of each compass cell + the gap between them. */
|
||||
const CELL = 38;
|
||||
@@ -1,4 +1,4 @@
|
||||
import { DockviewModule } from 'dockview-core';
|
||||
import { DockviewModule, registerModules } from 'dockview';
|
||||
import { TabGroupChipsModule } from './tabGroupChipsService';
|
||||
import { ContextMenuModule } from './contextMenu';
|
||||
import { AccessibilityModule } from './accessibilityService';
|
||||
@@ -9,6 +9,13 @@ import { AutoHideEdgeGroupModule } from './autoHideEdgeGroupService';
|
||||
import { MultiRowTabsModule } from './multiRowTabsService';
|
||||
import { PinnedTabsModule } from './pinnedTabsService';
|
||||
import { KeyboardDockingModule } from './keyboardDockingService';
|
||||
import { LicenseModule } from './licenseService';
|
||||
|
||||
// Re-export the full dockview (free) API so `dockview-enterprise` is a drop-in
|
||||
// superset — mirrors AG Grid's `ag-grid-enterprise` re-exporting
|
||||
// `ag-grid-community`. Also runs dockview's own load-time side effects
|
||||
// (e.g. markDockviewPackageLoaded) via the re-exported module.
|
||||
export * from 'dockview';
|
||||
|
||||
export {
|
||||
TabGroupChipsService,
|
||||
@@ -49,8 +56,10 @@ export type {
|
||||
export type { LicenseState } from './licenseValidator';
|
||||
|
||||
/**
|
||||
* The set of modules provided by this package. `dockview` registers these via
|
||||
* `registerModules(Modules)` so they are available to every component.
|
||||
* The enterprise feature modules, including the license gate. Registered
|
||||
* automatically on import (below), so merely importing `dockview-enterprise`
|
||||
* activates these modules — and the license watermark-unless-licensed check —
|
||||
* for every component in the process.
|
||||
*/
|
||||
export const Modules: DockviewModule<any>[] = [
|
||||
TabGroupChipsModule,
|
||||
@@ -63,4 +72,10 @@ export const Modules: DockviewModule<any>[] = [
|
||||
MultiRowTabsModule,
|
||||
PinnedTabsModule,
|
||||
KeyboardDockingModule,
|
||||
LicenseModule,
|
||||
];
|
||||
|
||||
// Self-register on import (a side effect — hence `sideEffects: true` in
|
||||
// package.json). This makes the package batteries-included: no explicit
|
||||
// registerModules() call is required of the consumer.
|
||||
registerModules(Modules);
|
||||
+9
-9
@@ -1,15 +1,15 @@
|
||||
import {
|
||||
DockviewCompositeDisposable as CompositeDisposable,
|
||||
DockviewIDisposable as IDisposable,
|
||||
} from 'dockview-core';
|
||||
import { Position } from 'dockview-core';
|
||||
import { DockviewGroupPanel } from 'dockview-core';
|
||||
import { IDockviewPanel } from 'dockview-core';
|
||||
import { resolveMessages } from 'dockview-core';
|
||||
import { defineModule } from 'dockview-core';
|
||||
import { AdvancedDnDModule } from 'dockview-core';
|
||||
import { LiveRegionModule } from 'dockview-core';
|
||||
import { IAccessibilityHost, IKeyboardDockingService } from 'dockview-core';
|
||||
} from 'dockview';
|
||||
import { Position } from 'dockview';
|
||||
import { DockviewGroupPanel } from 'dockview';
|
||||
import { IDockviewPanel } from 'dockview';
|
||||
import { resolveMessages } from 'dockview';
|
||||
import { defineModule } from 'dockview';
|
||||
import { AdvancedDnDModule } from 'dockview';
|
||||
import { LiveRegionModule } from 'dockview';
|
||||
import { IAccessibilityHost, IKeyboardDockingService } from 'dockview';
|
||||
import {
|
||||
bindDocumentListeners,
|
||||
KEYBOARD_MOVE_ATTRIBUTE,
|
||||
+1
-1
@@ -2,7 +2,7 @@ import {
|
||||
DockviewComponentOptions,
|
||||
DockviewIDisposable as IDisposable,
|
||||
KeyboardNavigationOptions,
|
||||
} from 'dockview-core';
|
||||
} from 'dockview';
|
||||
|
||||
/**
|
||||
* Marks (on the dockview root element) that a keyboard move is in progress, so
|
||||
+4
-4
@@ -2,20 +2,20 @@ import {
|
||||
DockviewCompositeDisposable as CompositeDisposable,
|
||||
DockviewEmitter as Emitter,
|
||||
DockviewEvent as Event,
|
||||
} from 'dockview-core';
|
||||
} from 'dockview';
|
||||
import {
|
||||
DockviewComponentOptions,
|
||||
DockviewLayoutMutationEvent,
|
||||
DockviewLayoutMutationKind,
|
||||
SerializedDockview,
|
||||
} from 'dockview-core';
|
||||
import { defineModule } from 'dockview-core';
|
||||
} from 'dockview';
|
||||
import { defineModule } from 'dockview';
|
||||
import {
|
||||
ILayoutHistoryHost,
|
||||
ILayoutHistoryService,
|
||||
LayoutHistoryChangeEvent,
|
||||
LayoutHistoryKind,
|
||||
} from 'dockview-core';
|
||||
} from 'dockview';
|
||||
|
||||
interface HistoryEntry {
|
||||
readonly kind: LayoutHistoryKind;
|
||||
+1
-1
@@ -11,7 +11,7 @@
|
||||
* license.md` §5.
|
||||
*/
|
||||
|
||||
import { DockviewEmitter, DockviewEvent } from 'dockview-core';
|
||||
import { DockviewEmitter, DockviewEvent } from 'dockview';
|
||||
|
||||
class LicenseRegistryImpl {
|
||||
private _key: string | undefined;
|
||||
+7
-8
@@ -13,10 +13,7 @@
|
||||
* contracts live in this package. See `enterprise-modules/license.md`.
|
||||
*/
|
||||
|
||||
import {
|
||||
defineModule,
|
||||
DockviewIDisposable as IDisposable,
|
||||
} from 'dockview-core';
|
||||
import { defineModule, DockviewIDisposable as IDisposable } from 'dockview';
|
||||
import {
|
||||
LicenseState,
|
||||
isLocalhostHostname,
|
||||
@@ -26,10 +23,12 @@ import {
|
||||
import { LicenseRegistry } from './licenseRegistry';
|
||||
import { DOCKVIEW_RELEASE_DATE } from './releaseDate';
|
||||
|
||||
// The `ServiceCollection` slot is added HERE, not in core — so `dockview-core`
|
||||
// never names `licenseService`. Compile-time only; the module system stores /
|
||||
// reads services by string key at runtime.
|
||||
declare module 'dockview-core' {
|
||||
// The `ServiceCollection` slot is added HERE, not in core — so core never names
|
||||
// `licenseService`. Augmenting `dockview` (which re-exports core's
|
||||
// `ServiceCollection`) keeps the package free of any `dockview-core` reference.
|
||||
// Compile-time only; the module system stores/reads services by string key at
|
||||
// runtime.
|
||||
declare module 'dockview' {
|
||||
interface ServiceCollection {
|
||||
licenseService?: ILicenseService;
|
||||
}
|
||||
+1
-1
@@ -2,7 +2,7 @@
|
||||
* License key validation — pure, dependency-free, synchronous.
|
||||
*
|
||||
* This is a re-implementation of the issuer's scheme
|
||||
* (`dockview-licencing/src/lib/{checksum,licence}.ts`) so `dockview-modules`
|
||||
* (`dockview-licencing/src/lib/{checksum,licence}.ts`) so `dockview-enterprise`
|
||||
* can verify a key entirely offline. It MUST stay byte-compatible with the
|
||||
* issuer — the cross-repo golden fixture in the spec (a real minted key) is
|
||||
* the guard against drift.
|
||||
+2
-2
@@ -4,8 +4,8 @@ import {
|
||||
DockviewOverflowOptions,
|
||||
OVERFLOW_WRAP_TABS_CLASS as WRAP_CLASS,
|
||||
defineModule,
|
||||
} from 'dockview-core';
|
||||
import { IMultiRowTabsHost, IMultiRowTabsService } from 'dockview-core';
|
||||
} from 'dockview';
|
||||
import { IMultiRowTabsHost, IMultiRowTabsService } from 'dockview';
|
||||
|
||||
function isWrapMode(overflow: DockviewOverflowOptions | undefined): boolean {
|
||||
return typeof overflow === 'object' && overflow?.mode === 'wrap';
|
||||
BIN
Binary file not shown.
+4
-4
@@ -2,7 +2,7 @@ import {
|
||||
DockviewCompositeDisposable as CompositeDisposable,
|
||||
DockviewEmitter as Emitter,
|
||||
DockviewEvent as Event,
|
||||
} from 'dockview-core';
|
||||
} from 'dockview';
|
||||
import {
|
||||
Box,
|
||||
DockviewGroupPanel,
|
||||
@@ -13,9 +13,9 @@ import {
|
||||
SmartGuidesSnapPosition,
|
||||
SmartGuidesSnapTogetherEvent,
|
||||
SnapModifier,
|
||||
} from 'dockview-core';
|
||||
import { defineModule, FloatingGroupModule } from 'dockview-core';
|
||||
import { ISmartGuidesHost, ISmartGuidesService } from 'dockview-core';
|
||||
} from 'dockview';
|
||||
import { defineModule, FloatingGroupModule } from 'dockview';
|
||||
import { ISmartGuidesHost, ISmartGuidesService } from 'dockview';
|
||||
|
||||
/** Fraction of the perpendicular extents that must overlap for an edge to read
|
||||
* as an adjacency (dock-beside) rather than a glancing touch. */
|
||||
+4
-4
@@ -1,10 +1,10 @@
|
||||
import {
|
||||
DockviewCompositeDisposable as CompositeDisposable,
|
||||
DockviewIDisposable as IDisposable,
|
||||
} from 'dockview-core';
|
||||
import { DockviewGroupPanel } from 'dockview-core';
|
||||
import { defineModule } from 'dockview-core';
|
||||
import { ITabGroupChipsHost, ITabGroupChipsService } from 'dockview-core';
|
||||
} from 'dockview';
|
||||
import { DockviewGroupPanel } from 'dockview';
|
||||
import { defineModule } from 'dockview';
|
||||
import { ITabGroupChipsHost, ITabGroupChipsService } from 'dockview';
|
||||
|
||||
export class TabGroupChipsService implements ITabGroupChipsService {
|
||||
private readonly _host: ITabGroupChipsHost;
|
||||
@@ -1 +0,0 @@
|
||||
AGENTS.md
|
||||
@@ -17,8 +17,8 @@ const config: JestConfigWithTsJest = {
|
||||
moduleNameMapper: {
|
||||
'^dockview-core$': '<rootDir>/packages/dockview-core/src/index.ts',
|
||||
'^dockview$': '<rootDir>/packages/dockview/src/index.ts',
|
||||
'^dockview-modules$':
|
||||
'<rootDir>/packages/dockview-modules/src/index.ts',
|
||||
'^dockview-enterprise$':
|
||||
'<rootDir>/packages/dockview-enterprise/src/index.ts',
|
||||
},
|
||||
modulePathIgnorePatterns: [
|
||||
'<rootDir>/packages/dockview-react/src/__tests__/__mocks__',
|
||||
|
||||
@@ -12,15 +12,16 @@ export default defineConfig({
|
||||
include: ['src/__tests__/**/*.spec.ts'],
|
||||
alias: {
|
||||
dockview: resolve(__dirname, '../dockview/src/index.ts'),
|
||||
'dockview-core': resolve(__dirname, '../dockview-core/src/index.ts'),
|
||||
'dockview-modules': resolve(
|
||||
'dockview-core': resolve(
|
||||
__dirname,
|
||||
'../dockview-modules/src/index.ts'
|
||||
'../dockview-core/src/index.ts'
|
||||
),
|
||||
'dockview-enterprise': resolve(
|
||||
__dirname,
|
||||
'../dockview-enterprise/src/index.ts'
|
||||
),
|
||||
},
|
||||
setupFiles: [
|
||||
'src/__tests__/__mocks__/resizeObserver.vitest.ts',
|
||||
],
|
||||
setupFiles: ['src/__tests__/__mocks__/resizeObserver.vitest.ts'],
|
||||
},
|
||||
|
||||
build: {
|
||||
|
||||
@@ -14,8 +14,8 @@ const config: JestConfigWithTsJest = {
|
||||
coveragePathIgnorePatterns: ['/node_modules/'],
|
||||
moduleNameMapper: {
|
||||
'^dockview-core$': '<rootDir>/packages/dockview-core/src/index.ts',
|
||||
'^dockview-modules$':
|
||||
'<rootDir>/packages/dockview-modules/src/index.ts',
|
||||
'^dockview-enterprise$':
|
||||
'<rootDir>/packages/dockview-enterprise/src/index.ts',
|
||||
},
|
||||
modulePathIgnorePatterns: [],
|
||||
coverageDirectory: '<rootDir>/packages/dockview/coverage/',
|
||||
|
||||
@@ -75,8 +75,5 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"dockview-core": "^7.0.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"dockview-modules": "^7.0.2"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -50,9 +50,10 @@ function createBundle(format, options) {
|
||||
|
||||
const isUMD = format === 'umd';
|
||||
|
||||
// dockview-modules is a private, unpublished package — always bundle its
|
||||
// code in. dockview-core is published: externalize it in the package
|
||||
// builds, but inline it in the UMD bundle so the CDN build is self-contained.
|
||||
// dockview-core is published: externalize it in the package builds, but
|
||||
// inline it in the UMD bundle so the CDN build is self-contained. (The
|
||||
// enterprise feature modules now live in the separately-published
|
||||
// dockview-enterprise package and are no longer bundled here.)
|
||||
const external = isUMD
|
||||
? ['react', 'react-dom']
|
||||
: ['react', 'react-dom', 'dockview-core', /^dockview-core\//];
|
||||
@@ -77,12 +78,10 @@ function createBundle(format, options) {
|
||||
|
||||
const plugins = [
|
||||
nodeResolve({
|
||||
include: isUMD
|
||||
? [
|
||||
'node_modules/dockview-core/**',
|
||||
'node_modules/dockview-modules/**',
|
||||
]
|
||||
: ['node_modules/dockview-modules/**'],
|
||||
// UMD is self-contained: bundle dockview-core in. Package builds
|
||||
// externalize dockview-core, so nothing needs bundling from
|
||||
// node_modules there.
|
||||
include: isUMD ? ['node_modules/dockview-core/**'] : [],
|
||||
}),
|
||||
typescript({
|
||||
tsconfig: 'tsconfig.esm.json',
|
||||
|
||||
@@ -1,15 +1,13 @@
|
||||
import { markDockviewPackageLoaded, registerModules } from 'dockview-core';
|
||||
import { Modules } from 'dockview-modules';
|
||||
import { markDockviewPackageLoaded } from 'dockview-core';
|
||||
|
||||
export * from 'dockview-core';
|
||||
|
||||
/**
|
||||
* `dockview` is the batteries-included entry point: it re-exports the core API
|
||||
* and registers the separable feature modules so every component gets the full
|
||||
* feature set out of the box. Consumers who want only the core can depend on
|
||||
* `dockview-core` directly.
|
||||
* `dockview` is the recommended free entry point: a thin re-export of
|
||||
* `dockview-core`. The separable enterprise feature modules now live in the
|
||||
* separately-published `dockview-enterprise` package (which depends on and
|
||||
* re-exports `dockview`); install that to opt into them.
|
||||
*/
|
||||
registerModules(Modules);
|
||||
|
||||
// Mark the public package as loaded so `dockview-core` doesn't warn about
|
||||
// direct usage. Purely drives that developer warning — no functional effect.
|
||||
|
||||
@@ -91,13 +91,13 @@ const config = {
|
||||
__dirname,
|
||||
'../dockview/src'
|
||||
),
|
||||
// Without this, dockview-modules resolves to
|
||||
// Without this, dockview-enterprise resolves to
|
||||
// its built dist/, so editing module source
|
||||
// (e.g. auto-hide edge groups) does nothing
|
||||
// until a rebuild + dev-server restart.
|
||||
'dockview-modules$': path.join(
|
||||
'dockview-enterprise$': path.join(
|
||||
__dirname,
|
||||
'../dockview-modules/src'
|
||||
'../dockview-enterprise/src'
|
||||
),
|
||||
}),
|
||||
react: path.join(
|
||||
|
||||
@@ -13,6 +13,14 @@ import {
|
||||
GetTabGroupChipContextMenuItemsParams,
|
||||
DEFAULT_TAB_GROUP_COLORS,
|
||||
} from 'dockview-react';
|
||||
// Side-effect import: registers the enterprise feature modules (pinned tabs,
|
||||
// smart guides, drop guide, auto-hide, context menu, tab-group chips, …) and
|
||||
// the license check into the global registry. Required now that the free
|
||||
// `dockview`/`dockview-react` packages no longer bundle them.
|
||||
// NOTE: on a deployed (non-localhost) origin this shows a license watermark
|
||||
// until `LicenseManager.setLicenseKey('<vendor key>')` is called; localhost
|
||||
// (the sandbox/dev preview) suppresses it.
|
||||
import 'dockview-enterprise';
|
||||
import * as React from 'react';
|
||||
import * as ReactDOM from 'react-dom/client';
|
||||
import './app.scss';
|
||||
|
||||
+1
-1
@@ -52,7 +52,7 @@
|
||||
// exports from a CJS module when that flag is present). `dockview`
|
||||
// is consumed only via `require()` from dockview-react, so it can
|
||||
// use the inlined `dist/package` bundle — which avoids the dangling
|
||||
// `require('dockview-modules')` present in its tsc `dist/cjs` build.
|
||||
// `require('dockview-enterprise')` present in its tsc `dist/cjs` build.
|
||||
'dockview-core': {
|
||||
main: './dist/cjs/index.js',
|
||||
format: 'cjs',
|
||||
|
||||
@@ -8,7 +8,7 @@ import { defineConfig, devices } from '@playwright/test';
|
||||
* static fixture page (built UMD bundles) in headless Chromium.
|
||||
*
|
||||
* Prerequisite: the UMD bundles must exist —
|
||||
* yarn nx run-many -t build:bundle -p dockview-core dockview-modules
|
||||
* yarn nx run-many -t build:bundle -p dockview-core dockview-enterprise
|
||||
* then `yarn test:e2e`.
|
||||
*/
|
||||
export default defineConfig({
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
sonar.projectKey=mathuo_dockview
|
||||
sonar.organization=dockview
|
||||
|
||||
sonar.inclusions=packages/dockview/src/**/*,packages/dockview-core/src/**/*,packages/dockview-vue/src/**/*,packages/dockview-react/src/**/*,packages/dockview-angular/src/**/*,packages/dockview-modules/src/**/*
|
||||
sonar.exclusions=packages/dockview/docs/**/*,packages/dockview/src/__tests__/**/*,packages/dockview-core/src/__tests__/**/*,packages/dockview-vue/src/__tests__/**/*,packages/dockview-react/src/__tests__/**/*,packages/dockview-angular/src/__tests__/**/*,packages/dockview-modules/src/__tests__/**/*
|
||||
sonar.tests=packages/dockview/src/__tests__,packages/dockview-core/src/__tests__,packages/dockview-vue/src/__tests__,packages/dockview-react/src/__tests__,packages/dockview-angular/src/__tests__,packages/dockview-modules/src/__tests__
|
||||
sonar.inclusions=packages/dockview/src/**/*,packages/dockview-core/src/**/*,packages/dockview-vue/src/**/*,packages/dockview-react/src/**/*,packages/dockview-angular/src/**/*,packages/dockview-enterprise/src/**/*
|
||||
sonar.exclusions=packages/dockview/docs/**/*,packages/dockview/src/__tests__/**/*,packages/dockview-core/src/__tests__/**/*,packages/dockview-vue/src/__tests__/**/*,packages/dockview-react/src/__tests__/**/*,packages/dockview-angular/src/__tests__/**/*,packages/dockview-enterprise/src/__tests__/**/*
|
||||
sonar.tests=packages/dockview/src/__tests__,packages/dockview-core/src/__tests__,packages/dockview-vue/src/__tests__,packages/dockview-react/src/__tests__,packages/dockview-angular/src/__tests__,packages/dockview-enterprise/src/__tests__
|
||||
|
||||
sonar.testExecutionReportPaths=test-report.xml
|
||||
sonar.javascript.lcov.reportPaths=coverage/lcov.info
|
||||
|
||||
+1
-1
@@ -8,7 +8,7 @@
|
||||
"path": "./packages/dockview-core"
|
||||
},
|
||||
{
|
||||
"path": "./packages/dockview-modules"
|
||||
"path": "./packages/dockview-enterprise"
|
||||
},
|
||||
{
|
||||
"path": "./packages/dockview-vue"
|
||||
|
||||
+1
-1
@@ -6,7 +6,7 @@
|
||||
"dockview-core": ["packages/dockview-core/src/index.ts"],
|
||||
"dockview": ["packages/dockview/src/index.ts"],
|
||||
"dockview-react": ["packages/dockview-react/src/index.ts"],
|
||||
"dockview-modules": ["packages/dockview-modules/src/index.ts"]
|
||||
"dockview-enterprise": ["packages/dockview-enterprise/src/index.ts"]
|
||||
},
|
||||
"jsx": "react-jsx",
|
||||
"noImplicitAny": false,
|
||||
|
||||
Reference in New Issue
Block a user