@cocoar/vue-script-editor 1.9.0-script-editor.4
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/LICENSE +201 -0
- package/README.md +278 -0
- package/dist/CoarScriptEditor.vue.d.ts +122 -0
- package/dist/CoarScriptEditor.vue.d.ts.map +1 -0
- package/dist/composables/useConstrainedRegions.d.ts +17 -0
- package/dist/composables/useConstrainedRegions.d.ts.map +1 -0
- package/dist/composables/useExtraLibs.d.ts +20 -0
- package/dist/composables/useExtraLibs.d.ts.map +1 -0
- package/dist/composables/useFormFieldContext.d.ts +17 -0
- package/dist/composables/useFormFieldContext.d.ts.map +1 -0
- package/dist/composables/useMonacoEditor.d.ts +58 -0
- package/dist/composables/useMonacoEditor.d.ts.map +1 -0
- package/dist/constrained/ChangeGuard.d.ts +43 -0
- package/dist/constrained/ChangeGuard.d.ts.map +1 -0
- package/dist/constrained/CursorGuard.d.ts +21 -0
- package/dist/constrained/CursorGuard.d.ts.map +1 -0
- package/dist/constrained/DiagnosticsFilter.d.ts +29 -0
- package/dist/constrained/DiagnosticsFilter.d.ts.map +1 -0
- package/dist/constrained/LockedLineScanner.d.ts +110 -0
- package/dist/constrained/LockedLineScanner.d.ts.map +1 -0
- package/dist/index.css +2 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +693 -0
- package/dist/theme.d.ts +35 -0
- package/dist/theme.d.ts.map +1 -0
- package/package.json +50 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useFormFieldContext.d.ts","sourceRoot":"","sources":["../../src/composables/useFormFieldContext.ts"],"names":[],"mappings":"AAAA,OAAO,EAAU,KAAK,WAAW,EAAqB,MAAM,KAAK,CAAC;AAElE;;;;;;;GAOG;AACH,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IAC7B,SAAS,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IAC/B,QAAQ,EAAE,WAAW,CAAC,OAAO,CAAC,CAAC;IAC/B,QAAQ,EAAE,WAAW,CAAC,OAAO,CAAC,CAAC;CAChC;AAMD,wBAAgB,mBAAmB,IAAI,gBAAgB,GAAG,SAAS,CAElE"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { Ref } from 'vue';
|
|
2
|
+
import { CoarScriptEditorTheme } from '../theme';
|
|
3
|
+
import * as monaco from 'monaco-editor';
|
|
4
|
+
export type CoarScriptEditorLanguage = 'typescript' | 'javascript' | 'json';
|
|
5
|
+
export type CoarScriptEditorVariant = 'editor' | 'inline';
|
|
6
|
+
export interface UseMonacoEditorOptions {
|
|
7
|
+
host: Ref<HTMLElement | null>;
|
|
8
|
+
initialValue: () => string;
|
|
9
|
+
language: () => CoarScriptEditorLanguage;
|
|
10
|
+
readonly: () => boolean;
|
|
11
|
+
minimap: () => boolean;
|
|
12
|
+
theme: () => CoarScriptEditorTheme;
|
|
13
|
+
variant?: () => CoarScriptEditorVariant;
|
|
14
|
+
/**
|
|
15
|
+
* Hidden + locked prefix prepended to the model content for per-editor type context.
|
|
16
|
+
* `setHiddenAreas` hides it from view, and an internal guard rejects any edit whose
|
|
17
|
+
* change offset falls inside the preamble range. Emitted value is the user-script
|
|
18
|
+
* portion only — preamble never round-trips through `modelValue`.
|
|
19
|
+
*/
|
|
20
|
+
preamble?: () => string;
|
|
21
|
+
/**
|
|
22
|
+
* When true, sets `diagnosticCodesToIgnore` on Monaco's TS/JS defaults to suppress the
|
|
23
|
+
* errors that normally fire on "script body" code (top-level return/await/export, etc).
|
|
24
|
+
* **Global side-effect** — affects all TS/JS editors on the page. Consumers needing
|
|
25
|
+
* granular control should manage `monaco.languages.typescript.typescriptDefaults`
|
|
26
|
+
* directly.
|
|
27
|
+
*/
|
|
28
|
+
scriptMode?: () => boolean;
|
|
29
|
+
autofocus?: () => boolean;
|
|
30
|
+
/**
|
|
31
|
+
* Optional override for where Monaco renders overflow widgets (IntelliSense popups,
|
|
32
|
+
* hover, parameter hints). When the editor is mounted inside a modal/overlay with its
|
|
33
|
+
* own stacking context, the default body-level container often ends up behind the modal
|
|
34
|
+
* or in the wrong stacking context. Pass an element from inside the modal to put the
|
|
35
|
+
* widgets there. Returning `null` means "use Monaco's default body-level container".
|
|
36
|
+
*/
|
|
37
|
+
overflowWidgetsDomNode?: () => HTMLElement | null;
|
|
38
|
+
onContentChange: (value: string) => void;
|
|
39
|
+
onFocused?: () => void;
|
|
40
|
+
onBlurred?: () => void;
|
|
41
|
+
onEditorReady?: (editor: monaco.editor.IStandaloneCodeEditor) => void;
|
|
42
|
+
}
|
|
43
|
+
export interface UseMonacoEditorResult {
|
|
44
|
+
editor: Readonly<Ref<monaco.editor.IStandaloneCodeEditor | null>>;
|
|
45
|
+
model: Readonly<Ref<monaco.editor.ITextModel | null>>;
|
|
46
|
+
/**
|
|
47
|
+
* Replace the editor value without re-emitting a change event. Used for external v-model updates.
|
|
48
|
+
*/
|
|
49
|
+
setValue: (value: string) => void;
|
|
50
|
+
/**
|
|
51
|
+
* Temporarily suppresses `onContentChange` callbacks during the given mutation. Useful when
|
|
52
|
+
* higher-level logic (e.g. constrained regions) rolls back an illegal edit and does not want
|
|
53
|
+
* the rollback to echo back to the host.
|
|
54
|
+
*/
|
|
55
|
+
withSuppressedChange: <T>(fn: () => T) => T;
|
|
56
|
+
}
|
|
57
|
+
export declare function useMonacoEditor(options: UseMonacoEditorOptions): UseMonacoEditorResult;
|
|
58
|
+
//# sourceMappingURL=useMonacoEditor.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useMonacoEditor.d.ts","sourceRoot":"","sources":["../../src/composables/useMonacoEditor.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,MAAM,eAAe,CAAC;AACxC,OAAO,EAAsC,KAAK,GAAG,EAAE,MAAM,KAAK,CAAC;AACnE,OAAO,EAIL,KAAK,qBAAqB,EAC3B,MAAM,UAAU,CAAC;AAmBlB,MAAM,MAAM,wBAAwB,GAAG,YAAY,GAAG,YAAY,GAAG,MAAM,CAAC;AAC5E,MAAM,MAAM,uBAAuB,GAAG,QAAQ,GAAG,QAAQ,CAAC;AAyD1D,MAAM,WAAW,sBAAsB;IACrC,IAAI,EAAE,GAAG,CAAC,WAAW,GAAG,IAAI,CAAC,CAAC;IAC9B,YAAY,EAAE,MAAM,MAAM,CAAC;IAC3B,QAAQ,EAAE,MAAM,wBAAwB,CAAC;IACzC,QAAQ,EAAE,MAAM,OAAO,CAAC;IACxB,OAAO,EAAE,MAAM,OAAO,CAAC;IACvB,KAAK,EAAE,MAAM,qBAAqB,CAAC;IACnC,OAAO,CAAC,EAAE,MAAM,uBAAuB,CAAC;IACxC;;;;;OAKG;IACH,QAAQ,CAAC,EAAE,MAAM,MAAM,CAAC;IACxB;;;;;;OAMG;IACH,UAAU,CAAC,EAAE,MAAM,OAAO,CAAC;IAC3B,SAAS,CAAC,EAAE,MAAM,OAAO,CAAC;IAC1B;;;;;;OAMG;IACH,sBAAsB,CAAC,EAAE,MAAM,WAAW,GAAG,IAAI,CAAC;IAClD,eAAe,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACzC,SAAS,CAAC,EAAE,MAAM,IAAI,CAAC;IACvB,SAAS,CAAC,EAAE,MAAM,IAAI,CAAC;IACvB,aAAa,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,qBAAqB,KAAK,IAAI,CAAC;CACvE;AAED,MAAM,WAAW,qBAAqB;IACpC,MAAM,EAAE,QAAQ,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,qBAAqB,GAAG,IAAI,CAAC,CAAC,CAAC;IAClE,KAAK,EAAE,QAAQ,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,UAAU,GAAG,IAAI,CAAC,CAAC,CAAC;IACtD;;OAEG;IACH,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAClC;;;;OAIG;IACH,oBAAoB,EAAE,CAAC,CAAC,EAAE,EAAE,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC;CAC7C;AAsDD,wBAAgB,eAAe,CAAC,OAAO,EAAE,sBAAsB,GAAG,qBAAqB,CAuPtF"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { LockedLine, ProtectedRange } from './LockedLineScanner';
|
|
2
|
+
import type * as monaco from 'monaco-editor';
|
|
3
|
+
export type ChangeGuardRejectReason = 'edit-overlaps-locked-line';
|
|
4
|
+
export interface ChangeGuardRejectEvent {
|
|
5
|
+
reason: ChangeGuardRejectReason;
|
|
6
|
+
/** 1-based line range of the rejected edit as reported by Monaco. */
|
|
7
|
+
range?: {
|
|
8
|
+
startLineNumber: number;
|
|
9
|
+
endLineNumber: number;
|
|
10
|
+
};
|
|
11
|
+
}
|
|
12
|
+
export interface ChangeGuardCallbacks {
|
|
13
|
+
onReject?: (event: ChangeGuardRejectEvent) => void;
|
|
14
|
+
onLinesUpdated?: (lines: readonly LockedLine[]) => void;
|
|
15
|
+
onContentChanged?: (value: string) => void;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Watches content changes on a Monaco model and rejects any edit that overlaps a locked
|
|
19
|
+
* line (including the line's trailing `\n`, so line-merging is blocked).
|
|
20
|
+
*
|
|
21
|
+
* Skipped automatically:
|
|
22
|
+
* - `event.isFlush` — a full-document replacement via `setValue` from outside; trusted.
|
|
23
|
+
* - `event.isUndoing` — the editor is replaying an undo (including our own rollback of an
|
|
24
|
+
* illegal edit). We just refresh our cached scan; the undo itself is trusted.
|
|
25
|
+
*
|
|
26
|
+
* When `authoring()` returns true the guard becomes a passive observer — no rejects.
|
|
27
|
+
*/
|
|
28
|
+
export declare class ChangeGuard {
|
|
29
|
+
private readonly editor;
|
|
30
|
+
private readonly authoring;
|
|
31
|
+
private readonly callbacks;
|
|
32
|
+
private readonly disposables;
|
|
33
|
+
private lockedLines;
|
|
34
|
+
private protectedRanges;
|
|
35
|
+
constructor(editor: monaco.editor.IStandaloneCodeEditor, authoring: () => boolean, callbacks?: ChangeGuardCallbacks);
|
|
36
|
+
dispose(): void;
|
|
37
|
+
getLockedLines(): readonly LockedLine[];
|
|
38
|
+
getProtectedRanges(): readonly ProtectedRange[];
|
|
39
|
+
/** Re-scan the model after an external change that bypassed onDidChangeContent. */
|
|
40
|
+
refresh(): void;
|
|
41
|
+
private handleChange;
|
|
42
|
+
}
|
|
43
|
+
//# sourceMappingURL=ChangeGuard.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ChangeGuard.d.ts","sourceRoot":"","sources":["../../src/constrained/ChangeGuard.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,MAAM,eAAe,CAAC;AAC7C,OAAO,EAIL,KAAK,UAAU,EACf,KAAK,cAAc,EACpB,MAAM,qBAAqB,CAAC;AAE7B,MAAM,MAAM,uBAAuB,GAAG,2BAA2B,CAAC;AAElE,MAAM,WAAW,sBAAsB;IACrC,MAAM,EAAE,uBAAuB,CAAC;IAChC,qEAAqE;IACrE,KAAK,CAAC,EAAE;QAAE,eAAe,EAAE,MAAM,CAAC;QAAC,aAAa,EAAE,MAAM,CAAA;KAAE,CAAC;CAC5D;AAED,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,sBAAsB,KAAK,IAAI,CAAC;IACnD,cAAc,CAAC,EAAE,CAAC,KAAK,EAAE,SAAS,UAAU,EAAE,KAAK,IAAI,CAAC;IACxD,gBAAgB,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;CAC5C;AAED;;;;;;;;;;GAUG;AACH,qBAAa,WAAW;IAMpB,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,SAAS;IAC1B,OAAO,CAAC,QAAQ,CAAC,SAAS;IAP5B,OAAO,CAAC,QAAQ,CAAC,WAAW,CAA4B;IACxD,OAAO,CAAC,WAAW,CAAe;IAClC,OAAO,CAAC,eAAe,CAAmB;gBAGvB,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,qBAAqB,EAC3C,SAAS,EAAE,MAAM,OAAO,EACxB,SAAS,GAAE,oBAAyB;IAWvD,OAAO,IAAI,IAAI;IAIf,cAAc,IAAI,SAAS,UAAU,EAAE;IAIvC,kBAAkB,IAAI,SAAS,cAAc,EAAE;IAI/C,mFAAmF;IACnF,OAAO,IAAI,IAAI;IAQf,OAAO,CAAC,YAAY;CAwCrB"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { ProtectedRange } from './LockedLineScanner';
|
|
2
|
+
import type * as monaco from 'monaco-editor';
|
|
3
|
+
/**
|
|
4
|
+
* Keeps cursors out of the interior of locked lines. When enforcement is on and a cursor
|
|
5
|
+
* endpoint lands strictly inside a protected range, it is snapped to the closer boundary.
|
|
6
|
+
*
|
|
7
|
+
* Reads protected ranges from a getter so the guard always uses the latest scan — ranges
|
|
8
|
+
* shift whenever content above a locked line changes.
|
|
9
|
+
*/
|
|
10
|
+
export declare class CursorGuard {
|
|
11
|
+
private readonly editor;
|
|
12
|
+
private readonly getRanges;
|
|
13
|
+
private readonly authoring;
|
|
14
|
+
private readonly disposables;
|
|
15
|
+
private correcting;
|
|
16
|
+
constructor(editor: monaco.editor.IStandaloneCodeEditor, getRanges: () => readonly ProtectedRange[], authoring: () => boolean);
|
|
17
|
+
dispose(): void;
|
|
18
|
+
snapCurrent(): void;
|
|
19
|
+
private handleSelectionChange;
|
|
20
|
+
}
|
|
21
|
+
//# sourceMappingURL=CursorGuard.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CursorGuard.d.ts","sourceRoot":"","sources":["../../src/constrained/CursorGuard.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,MAAM,eAAe,CAAC;AAC7C,OAAO,EAA4B,KAAK,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAEpF;;;;;;GAMG;AACH,qBAAa,WAAW;IAKpB,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,SAAS;IAC1B,OAAO,CAAC,QAAQ,CAAC,SAAS;IAN5B,OAAO,CAAC,QAAQ,CAAC,WAAW,CAA4B;IACxD,OAAO,CAAC,UAAU,CAAS;gBAGR,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,qBAAqB,EAC3C,SAAS,EAAE,MAAM,SAAS,cAAc,EAAE,EAC1C,SAAS,EAAE,MAAM,OAAO;IAO3C,OAAO,IAAI,IAAI;IAIf,WAAW,IAAI,IAAI;IAInB,OAAO,CAAC,qBAAqB;CA6C9B"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import * as monaco from 'monaco-editor';
|
|
2
|
+
/**
|
|
3
|
+
* Suppresses error-severity TypeScript markers that fall on locked lines.
|
|
4
|
+
*
|
|
5
|
+
* Why: when a user types an incomplete body (e.g. an unbalanced `}`), the TS parser's
|
|
6
|
+
* recovery often flags the surrounding *signature* as a syntax error. For the user that
|
|
7
|
+
* signature appears broken, even though they never touched it — and can't fix it anyway.
|
|
8
|
+
* We hide those errors until the body stabilises.
|
|
9
|
+
*
|
|
10
|
+
* Scope:
|
|
11
|
+
* - Only the editor's own model is filtered.
|
|
12
|
+
* - Only severity `Error` markers; warnings and info are left alone.
|
|
13
|
+
* - When `authoring()` returns true (template authoring), the filter stands down — the
|
|
14
|
+
* author needs to see every diagnostic.
|
|
15
|
+
*/
|
|
16
|
+
export declare class DiagnosticsFilter {
|
|
17
|
+
private readonly editor;
|
|
18
|
+
private readonly authoring;
|
|
19
|
+
private readonly disposables;
|
|
20
|
+
/** Re-entrancy guard: our own `setModelMarkers` fires `onDidChangeMarkers` again. */
|
|
21
|
+
private filtering;
|
|
22
|
+
constructor(editor: monaco.editor.IStandaloneCodeEditor, authoring: () => boolean);
|
|
23
|
+
dispose(): void;
|
|
24
|
+
/** Force a re-scan + re-filter — useful after the markers set changes externally. */
|
|
25
|
+
refresh(): void;
|
|
26
|
+
private handleMarkerChange;
|
|
27
|
+
private filterMarkers;
|
|
28
|
+
}
|
|
29
|
+
//# sourceMappingURL=DiagnosticsFilter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DiagnosticsFilter.d.ts","sourceRoot":"","sources":["../../src/constrained/DiagnosticsFilter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,MAAM,eAAe,CAAC;AAGxC;;;;;;;;;;;;;GAaG;AACH,qBAAa,iBAAiB;IAM1B,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,SAAS;IAN5B,OAAO,CAAC,QAAQ,CAAC,WAAW,CAA4B;IACxD,qFAAqF;IACrF,OAAO,CAAC,SAAS,CAAS;gBAGP,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,qBAAqB,EAC3C,SAAS,EAAE,MAAM,OAAO;IAS3C,OAAO,IAAI,IAAI;IAIf,qFAAqF;IACrF,OAAO,IAAI,IAAI;IAIf,OAAO,CAAC,kBAAkB;IAQ1B,OAAO,CAAC,aAAa;CAoDtB"}
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Line-based locking.
|
|
3
|
+
*
|
|
4
|
+
* Any line containing `// @locked` (optionally followed by more text) is protected:
|
|
5
|
+
* the user cannot edit, merge, or delete that line. The marker is an ordinary line
|
|
6
|
+
* comment, so the locked source is a valid `.ts`/`.js` file in any toolchain.
|
|
7
|
+
*
|
|
8
|
+
* function describeOrder(order: Order): string { // @locked
|
|
9
|
+
* return 'hi';
|
|
10
|
+
* } // @locked
|
|
11
|
+
*
|
|
12
|
+
* Matches are case-sensitive and require a word boundary after `locked` so lines like
|
|
13
|
+
* `// @lockedx` do not trigger.
|
|
14
|
+
*/
|
|
15
|
+
export declare const LOCKED_MARKER_TEXT = "// @locked";
|
|
16
|
+
export interface LockedLine {
|
|
17
|
+
/** 0-based line index within the source. */
|
|
18
|
+
lineIndex: number;
|
|
19
|
+
/** First offset of the line (character immediately after the previous `\n`, or 0). */
|
|
20
|
+
lineStart: number;
|
|
21
|
+
/**
|
|
22
|
+
* Offset of the `\n` terminating the line, or `source.length` for the last line with no
|
|
23
|
+
* trailing newline. This is an **inclusive** upper bound on the protected range — inserts
|
|
24
|
+
* and deletes that touch this offset belong to the locked line.
|
|
25
|
+
*/
|
|
26
|
+
lineEnd: number;
|
|
27
|
+
/**
|
|
28
|
+
* Start offset of the protected range. Equals `lineStart` — an insertion at this offset
|
|
29
|
+
* extends the locked line's content, so it is protected.
|
|
30
|
+
*/
|
|
31
|
+
protectedStart: number;
|
|
32
|
+
/**
|
|
33
|
+
* End offset of the protected range, **inclusive**. Equals `lineEnd`. An insertion at
|
|
34
|
+
* this offset extends the locked line's content (before the `\n`), a deletion of this
|
|
35
|
+
* offset removes the `\n` and merges the next line in — both protected.
|
|
36
|
+
*/
|
|
37
|
+
protectedEnd: number;
|
|
38
|
+
/** Valid snap target before the locked line (end of the previous line), or null if this is the first line. */
|
|
39
|
+
snapBefore: number | null;
|
|
40
|
+
/** Valid snap target after the locked line (start of the next line), or null if this is the last line with no trailing `\n`. */
|
|
41
|
+
snapAfter: number | null;
|
|
42
|
+
}
|
|
43
|
+
/** Contiguous protected range, produced by merging adjacent locked lines. */
|
|
44
|
+
export interface ProtectedRange {
|
|
45
|
+
start: number;
|
|
46
|
+
end: number;
|
|
47
|
+
/** Valid snap target before the block, or null if the block starts at file begin. */
|
|
48
|
+
snapBefore: number | null;
|
|
49
|
+
/** Valid snap target after the block, or null if the block ends at file end with no trailing `\n`. */
|
|
50
|
+
snapAfter: number | null;
|
|
51
|
+
}
|
|
52
|
+
export declare function hasLockedMarkers(source: string): boolean;
|
|
53
|
+
export declare function scanLockedLines(source: string): LockedLine[];
|
|
54
|
+
/**
|
|
55
|
+
* Merge adjacent locked lines into contiguous blocks. Two locks are adjacent when the next
|
|
56
|
+
* one begins exactly one character after the previous one ends (the `\n` between them). The
|
|
57
|
+
* resulting `ProtectedRange`s propagate the outermost `snapBefore` / `snapAfter`.
|
|
58
|
+
*/
|
|
59
|
+
export declare function computeProtectedRanges(lines: readonly LockedLine[]): ProtectedRange[];
|
|
60
|
+
/**
|
|
61
|
+
* Inclusive overlap test: does an edit `[rangeStart, rangeEnd]` touch the protected range
|
|
62
|
+
* `[range.start, range.end]`? Uses inclusive bounds on both sides — an insertion exactly at
|
|
63
|
+
* `range.start` or `range.end` counts as overlap, because both positions would extend the
|
|
64
|
+
* locked line's content.
|
|
65
|
+
*/
|
|
66
|
+
export declare function overlapsProtectedRange(edit: {
|
|
67
|
+
rangeStart: number;
|
|
68
|
+
rangeEnd: number;
|
|
69
|
+
}, range: ProtectedRange): boolean;
|
|
70
|
+
export declare function editIsProtected(edit: {
|
|
71
|
+
rangeStart: number;
|
|
72
|
+
rangeEnd: number;
|
|
73
|
+
}, ranges: readonly ProtectedRange[]): boolean;
|
|
74
|
+
/**
|
|
75
|
+
* Snap an offset away from protected territory. If the offset lies inside any protected
|
|
76
|
+
* range (inclusive), snap to the nearer valid free position. For first-line locks the only
|
|
77
|
+
* valid target is `snapAfter`; for last-line locks without a trailing `\n`, only `snapBefore`
|
|
78
|
+
* is valid. Returns `0` as ultimate fallback if neither side is valid (fully-locked file).
|
|
79
|
+
*/
|
|
80
|
+
export declare function snapOffsetAwayFromLocked(offset: number, ranges: readonly ProtectedRange[]): number;
|
|
81
|
+
/** Number of lines that carry a `// @locked` marker. */
|
|
82
|
+
export declare function countLockedLines(source: string): number;
|
|
83
|
+
/**
|
|
84
|
+
* Common submit-gate check: true when every editable segment contains at least one
|
|
85
|
+
* non-whitespace character. "Every body has been filled in."
|
|
86
|
+
*/
|
|
87
|
+
export declare function isEverySegmentNonEmpty(source: string): boolean;
|
|
88
|
+
export interface SourceValidation {
|
|
89
|
+
/** Always present — the scanner never throws. Indicates whether any warnings surfaced. */
|
|
90
|
+
ok: boolean;
|
|
91
|
+
lockedLineCount: number;
|
|
92
|
+
segmentCount: number;
|
|
93
|
+
/**
|
|
94
|
+
* Informational warnings the consumer may want to surface. Examples:
|
|
95
|
+
* "source starts with a locked line — imports cannot be added above it".
|
|
96
|
+
*/
|
|
97
|
+
warnings: string[];
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Quick structural check for a template or persisted source. Non-throwing; use it when you
|
|
101
|
+
* want to surface soft warnings (e.g. during template authoring) without refusing to mount.
|
|
102
|
+
*/
|
|
103
|
+
export declare function validateSource(source: string): SourceValidation;
|
|
104
|
+
/**
|
|
105
|
+
* Returns the text of each *editable* block — the stretches of consecutive non-locked
|
|
106
|
+
* lines. If the source has no locked lines, returns a single-element array with the full
|
|
107
|
+
* source. Useful for validation like "every block contains at least one non-empty line".
|
|
108
|
+
*/
|
|
109
|
+
export declare function getEditableSegments(source: string): string[];
|
|
110
|
+
//# sourceMappingURL=LockedLineScanner.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"LockedLineScanner.d.ts","sourceRoot":"","sources":["../../src/constrained/LockedLineScanner.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAIH,eAAO,MAAM,kBAAkB,eAAe,CAAC;AAE/C,MAAM,WAAW,UAAU;IACzB,4CAA4C;IAC5C,SAAS,EAAE,MAAM,CAAC;IAClB,sFAAsF;IACtF,SAAS,EAAE,MAAM,CAAC;IAClB;;;;OAIG;IACH,OAAO,EAAE,MAAM,CAAC;IAChB;;;OAGG;IACH,cAAc,EAAE,MAAM,CAAC;IACvB;;;;OAIG;IACH,YAAY,EAAE,MAAM,CAAC;IACrB,8GAA8G;IAC9G,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,gIAAgI;IAChI,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;CAC1B;AAED,6EAA6E;AAC7E,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;IACZ,qFAAqF;IACrF,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,sGAAsG;IACtG,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;CAC1B;AAED,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAExD;AAED,wBAAgB,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG,UAAU,EAAE,CA8B5D;AAED;;;;GAIG;AACH,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,SAAS,UAAU,EAAE,GAAG,cAAc,EAAE,CA6BrF;AAED;;;;;GAKG;AACH,wBAAgB,sBAAsB,CACpC,IAAI,EAAE;IAAE,UAAU,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,EAC9C,KAAK,EAAE,cAAc,GACpB,OAAO,CAET;AAED,wBAAgB,eAAe,CAC7B,IAAI,EAAE;IAAE,UAAU,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,EAC9C,MAAM,EAAE,SAAS,cAAc,EAAE,GAChC,OAAO,CAET;AAED;;;;;GAKG;AACH,wBAAgB,wBAAwB,CACtC,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,SAAS,cAAc,EAAE,GAChC,MAAM,CAYR;AAED,wDAAwD;AACxD,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAEvD;AAED;;;GAGG;AACH,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAE9D;AAED,MAAM,WAAW,gBAAgB;IAC/B,0FAA0F;IAC1F,EAAE,EAAE,OAAO,CAAC;IACZ,eAAe,EAAE,MAAM,CAAC;IACxB,YAAY,EAAE,MAAM,CAAC;IACrB;;;OAGG;IACH,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,gBAAgB,CAoB/D;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,CAuB5D"}
|
package/dist/index.css
ADDED
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
.coar-script-editor{border:1px solid var(--coar-border-input,var(--coar-border-neutral-tertiary,#e5e7eb));border-radius:var(--coar-radius-xs,4px);background:var(--coar-background-neutral-primary,#fff);width:100%;height:100%;min-height:200px;transition:border-color var(--coar-duration-fast,.15s) var(--coar-ease-out,ease-out), box-shadow var(--coar-duration-fast,.15s) var(--coar-ease-out,ease-out);--coar-script-editor-marker-scale:.6;--coar-script-editor-marker-opacity:.45;--coar-script-editor-marker-color:var(--coar-text-neutral-tertiary,#6b7280);--coar-script-editor-locked-line-bg:color-mix(in srgb, var(--coar-text-neutral-tertiary,#6b7280) 6%, transparent);display:block;position:relative;overflow:hidden}.coar-script-editor--inline{min-height:0}.coar-script-editor--inline:not(.coar-script-editor--disabled):hover{border-color:var(--coar-border-input-hover,#9ca3af)}.coar-script-editor--inline:focus-within:not(.coar-script-editor--error){border-color:var(--coar-focus-color,#3b82f6);box-shadow:inset 0 0 0 1px var(--coar-focus-color,#3b82f6)}.coar-script-editor--error{border-color:var(--coar-border-semantic-error-bold,#dc2626)}.coar-script-editor--error:focus-within{border-color:var(--coar-border-semantic-error-bold,#dc2626);box-shadow:inset 0 0 0 1px var(--coar-border-semantic-error-bold,#dc2626)}.coar-script-editor--disabled{opacity:.6;cursor:not-allowed;pointer-events:none;background:var(--coar-surface-input-disabled,#f3f4f6)}.coar-script-editor--show-placeholder:after{content:attr(data-placeholder);color:var(--coar-text-placeholder,#9ca3af);pointer-events:none;white-space:pre-line;z-index:1;font-family:Fira Code,Cascadia Code,Consolas,monospace;font-size:13px;position:absolute;top:8px;left:12px}.coar-script-editor:not(.coar-script-editor--inline).coar-script-editor--show-placeholder:after{left:68px}.coar-script-editor--authoring{--coar-script-editor-marker-scale:1;--coar-script-editor-marker-opacity:.85;--coar-script-editor-marker-color:var(--coar-text-warning,#b45309);--coar-script-editor-locked-line-bg:color-mix(in srgb, var(--coar-text-warning,#b45309) 10%, transparent)}.coar-script-editor-locked-line{background:var(--coar-script-editor-locked-line-bg)}.coar-script-editor-locked-marker{font-size:calc(1em * var(--coar-script-editor-marker-scale));opacity:var(--coar-script-editor-marker-opacity);letter-spacing:-.02em;color:var(--coar-script-editor-marker-color)}
|
|
2
|
+
/*$vite$:1*/
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export { default as CoarScriptEditor } from './CoarScriptEditor.vue';
|
|
2
|
+
export type { CoarScriptEditorProps, CoarScriptEditorRejectReason, CoarScriptEditorRejectEvent, } from './CoarScriptEditor.vue';
|
|
3
|
+
export type { CoarScriptEditorLanguage, CoarScriptEditorVariant, } from './composables/useMonacoEditor';
|
|
4
|
+
export type { CoarScriptEditorExtraLib } from './composables/useExtraLibs';
|
|
5
|
+
export type { CoarScriptEditorTheme } from './theme';
|
|
6
|
+
export { COAR_THEME_LIGHT, COAR_THEME_DARK, ensureCoarThemes, detectAutoTheme, watchAutoTheme, } from './theme';
|
|
7
|
+
export { scanLockedLines, computeProtectedRanges, hasLockedMarkers, getEditableSegments, overlapsProtectedRange, editIsProtected, snapOffsetAwayFromLocked, countLockedLines, isEverySegmentNonEmpty, validateSource, LOCKED_MARKER_TEXT, type LockedLine, type ProtectedRange, type SourceValidation, } from './constrained/LockedLineScanner';
|
|
8
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,IAAI,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AACrE,YAAY,EACV,qBAAqB,EACrB,4BAA4B,EAC5B,2BAA2B,GAC5B,MAAM,wBAAwB,CAAC;AAChC,YAAY,EACV,wBAAwB,EACxB,uBAAuB,GACxB,MAAM,+BAA+B,CAAC;AACvC,YAAY,EAAE,wBAAwB,EAAE,MAAM,4BAA4B,CAAC;AAC3E,YAAY,EAAE,qBAAqB,EAAE,MAAM,SAAS,CAAC;AACrD,OAAO,EACL,gBAAgB,EAChB,eAAe,EACf,gBAAgB,EAChB,eAAe,EACf,cAAc,GACf,MAAM,SAAS,CAAC;AAEjB,OAAO,EACL,eAAe,EACf,sBAAsB,EACtB,gBAAgB,EAChB,mBAAmB,EACnB,sBAAsB,EACtB,eAAe,EACf,wBAAwB,EACxB,gBAAgB,EAChB,sBAAsB,EACtB,cAAc,EACd,kBAAkB,EAClB,KAAK,UAAU,EACf,KAAK,cAAc,EACnB,KAAK,gBAAgB,GACtB,MAAM,iCAAiC,CAAC"}
|