Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@neo4j-cypher/react-codemirror

Package Overview
Dependencies
Maintainers
0
Versions
134
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@neo4j-cypher/react-codemirror - npm Package Compare versions

Comparing version 2.0.0-canary-04ae35e to 2.0.0-canary-05663bd

dist/constants.d.ts

24

CHANGELOG.md
# @neo4j-cypher/react-codemirror
## 2.0.0-next.10
### Patch Changes
- bb7e9d3: Simplify detection and handling of value prop updates
## 2.0.0-next.9
### Patch Changes
- fbd5f7e: allow signature help panel to render below editor when there's not enough space above it
- 09dfae2: Add an ariaLabel prop to CypherEditor
- 7154e94: Fix bug causing debouncing to override value
- 62c152f: execute single line query on enter by default
- cbfc75e: Fix a bug causing debounced value updates to get cancelled erroneously
- 04ae35e: Set initial latestDispatchedValue and flush debounced changes onExecute
Add tests for debounce behaviour
- Updated dependencies [3661e9d]
- Updated dependencies [b76af58]
- Updated dependencies [21699b7]
- Updated dependencies [6afc0e3]
- Updated dependencies [39b924d]
- @neo4j-cypher/language-support@2.0.0-next.7
## 2.0.0-next.8

@@ -4,0 +28,0 @@

1

dist/CypherEditor.d.ts

@@ -159,3 +159,2 @@ import { EditorState, Extension } from '@codemirror/state';

private schemaRef;
private latestDispatchedValue;
/**

@@ -162,0 +161,0 @@ * Focus the editor

@@ -7,2 +7,3 @@ import { jsx as _jsx } from "react/jsx-runtime";

import { Component, createRef } from 'react';
import { DEBOUNCE_TIME } from './constants';
import { replaceHistory, replMode as historyNavigation, } from './historyNavigation';

@@ -91,3 +92,2 @@ import { cypher } from './lang-cypher/langCypher';

schemaRef = createRef();
latestDispatchedValue;
/**

@@ -137,5 +137,4 @@ * Focus the editor

? debounce(((value, viewUpdate) => {
this.latestDispatchedValue = value;
this.props.onChange(value, viewUpdate);
}), 200)
}), DEBOUNCE_TIME)
: undefined;

@@ -172,7 +171,6 @@ componentDidMount() {

: [];
this.latestDispatchedValue = this.props.value;
this.editorState.current = EditorState.create({
extensions: [
keyBindingCompartment.of(keymap.of([
...executeKeybinding(onExecute, newLineOnEnter, () => this.debouncedOnChange.flush()),
...executeKeybinding(onExecute, newLineOnEnter, () => this.debouncedOnChange?.flush()),
...extraKeybindings,

@@ -222,5 +220,6 @@ ])),

const currentCmValue = this.editorView.current.state?.doc.toString() ?? '';
if (this.props.value !== undefined &&
this.props.value !== this.latestDispatchedValue) {
this.debouncedOnChange?.cancel();
if (this.props.value !== undefined && // If the component becomes uncontolled, we just leave the value as is
this.props.value !== prevProps.value && // The value prop has changed, we need to update the editor
this.props.value !== currentCmValue // No need to dispatch an update if the value is the same
) {
this.editorView.current.dispatch({

@@ -266,3 +265,3 @@ changes: {

effects: keyBindingCompartment.reconfigure(keymap.of([
...executeKeybinding(this.props.onExecute, this.props.newLineOnEnter, () => this.debouncedOnChange.flush()),
...executeKeybinding(this.props.onExecute, this.props.newLineOnEnter, () => this.debouncedOnChange?.flush()),
...this.props.extraKeybindings,

@@ -269,0 +268,0 @@ ])),

@@ -41,2 +41,20 @@ import { jsx as _jsx } from "react/jsx-runtime";

});
test('get completions when typing in controlled component', async ({ mount, page, }) => {
let value = '';
const onChange = (val) => {
value = val;
void component.update(_jsx(CypherEditor, { value: val, onChange: onChange }));
};
const component = await mount(_jsx(CypherEditor, { value: value, onChange: onChange }));
const textField = page.getByRole('textbox');
await textField.fill('RETU');
await page.waitForTimeout(500); // wait for debounce
await expect(page.locator('.cm-tooltip-autocomplete').getByText('RETURN')).toBeVisible();
// We need to wait for the editor to realise there is a completion open
// so that it does not just indent with tab key
await page.waitForTimeout(500);
await textField.press('Tab');
await expect(page.locator('.cm-tooltip-autocomplete')).not.toBeVisible();
await expect(component).toContainText('RETURN');
});
test('can complete labels', async ({ mount, page }) => {

@@ -43,0 +61,0 @@ const component = await mount(_jsx(CypherEditor, { schema: {

import { jsx as _jsx } from "react/jsx-runtime";
import { expect, test } from '@playwright/experimental-ct-react';
import { DEBOUNCE_TIME } from '../constants';
import { CypherEditor } from '../CypherEditor';
import { CypherEditorPage } from './e2eUtils';
const DEBOUNCE_TIMER = 200;
test('external updates should override debounced updates', async ({ mount, page, }) => {
const DEBOUNCE_TIME_WITH_MARGIN = DEBOUNCE_TIME + 100;
// value updates from outside onExecute are overwritten by pending updates
test.fail('external updates should override debounced updates', async ({ mount, page }) => {
const editorPage = new CypherEditorPage(page);

@@ -16,3 +18,3 @@ let value = '';

onChange('foo');
await page.waitForTimeout(DEBOUNCE_TIMER);
await page.waitForTimeout(DEBOUNCE_TIME_WITH_MARGIN);
await expect(component).toContainText('foo');

@@ -33,4 +35,4 @@ });

await editorPage.getEditor().pressSequentially('RETURN 1');
await editorPage.getEditor().press('Control+Enter');
await page.waitForTimeout(DEBOUNCE_TIMER);
await editorPage.getEditor().press('Enter');
await page.waitForTimeout(DEBOUNCE_TIME_WITH_MARGIN);
await expect(component).not.toContainText('RETURN 1');

@@ -40,4 +42,4 @@ await editorPage.getEditor().pressSequentially('RETURN 1');

await editorPage.getEditor().pressSequentially('RETURN 1');
await editorPage.getEditor().press('Control+Enter');
await page.waitForTimeout(DEBOUNCE_TIMER);
await editorPage.getEditor().press('Enter');
await page.waitForTimeout(DEBOUNCE_TIME_WITH_MARGIN);
await expect(component).not.toContainText('RETURN 1');

@@ -59,6 +61,6 @@ });

await editorPage.getEditor().fill('RETURN 1');
await editorPage.getEditor().press('Control+Enter');
await editorPage.getEditor().press('Enter');
await editorPage.getEditor().fill('RETURN 2');
await editorPage.getEditor().press('Control+Enter');
await page.waitForTimeout(DEBOUNCE_TIMER);
await editorPage.getEditor().press('Enter');
await page.waitForTimeout(DEBOUNCE_TIME_WITH_MARGIN);
await expect(component).toContainText('RETURN 2');

@@ -65,0 +67,0 @@ expect(executedCommand).toBe('RETURN 2');

@@ -24,3 +24,5 @@ import { jsx as _jsx } from "react/jsx-runtime";

const textField = page.getByRole('textbox');
await textField.fill('');
await textField.fill('RETURN 12');
await expect(textField).toHaveText('RETURN 12');
// editor update is debounced, retry wait for debounced

@@ -30,6 +32,2 @@ await expect(() => {

}).toPass({ intervals: [300, 300, 1000] });
await page.keyboard.type('34');
await expect(() => {
expect(editorValueCopy).toBe('RETURN 12');
}).toPass({ intervals: [300, 300, 1000] });
});

@@ -36,0 +34,0 @@ test('can complete RETURN', async ({ page, mount }) => {

import { tags } from '@lezer/highlight';
import { applySyntaxColouring, CypherTokenType, } from '@neo4j-cypher/language-support';
import { expect, test } from 'vitest';
import { tokenTypeToStyleTag } from './constants';

@@ -4,0 +5,0 @@ const cypherQueryWithAllTokenTypes = `MATCH (variable :Label)-[:REL_TYPE]->()

@@ -5,5 +5,3 @@ import { linter } from '@codemirror/lint';

import workerpool from 'workerpool';
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore ignore: https://v3.vitejs.dev/guide/features.html#import-with-query-suffixes
import WorkerURL from './lintWorker?url&worker';
import WorkerURL from './lintWorker?worker&url';
const pool = workerpool.pool(WorkerURL, {

@@ -10,0 +8,0 @@ minWorkers: 2,

import { tokens } from '@neo4j-ndl/base';
import { expect, test } from 'vitest';
import { tokens as tokensCopy } from './ndlTokensCopy';

@@ -3,0 +4,0 @@ /*

@@ -20,3 +20,3 @@ {

],
"version": "2.0.0-canary-04ae35e",
"version": "2.0.0-canary-05663bd",
"main": "./dist/index.js",

@@ -29,3 +29,3 @@ "types": "./dist/index.d.ts",

"clean": "rm -rf dist",
"test": "jest",
"test": "vitest run",
"test:e2e": "playwright test -c playwright-ct.config.ts",

@@ -53,6 +53,6 @@ "test:e2e-ui": "playwright test -c playwright-ct.config.ts --ui",

"@codemirror/state": "^6.4.1",
"@codemirror/view": "^6.28.4",
"@codemirror/view": "^6.29.1",
"@lezer/common": "^1.0.2",
"@lezer/highlight": "^1.1.3",
"@neo4j-cypher/language-support": "2.0.0-canary-04ae35e",
"@neo4j-cypher/language-support": "2.0.0-canary-05663bd",
"@types/prismjs": "^1.26.3",

@@ -69,13 +69,15 @@ "@types/workerpool": "^6.4.7",

"@neo4j-ndl/base": "^1.10.1",
"@playwright/experimental-ct-react": "^1.39.0",
"@playwright/test": "^1.36.2",
"@playwright/experimental-ct-react": "^1.45.3",
"@playwright/test": "^1.45.3",
"@types/lodash.debounce": "^4.0.9",
"@types/react": "^18.0.28",
"@vitejs/plugin-react": "^3.1.0",
"@vitejs/plugin-react": "^4.3.1",
"concurrently": "^8.2.1",
"esbuild": "^0.19.4",
"jsdom": "^24.1.1",
"lodash": "^4.17.21",
"playwright": "^1.36.2",
"playwright": "^1.45.3",
"react": "^18.2.0",
"typescript": "^4.9.5"
"typescript": "^4.9.5",
"vite": "^5.3.5"
},

@@ -82,0 +84,0 @@ "peerDependencies": {

@@ -6,2 +6,3 @@ import { tags } from '@lezer/highlight';

} from '@neo4j-cypher/language-support';
import { expect, test } from 'vitest';
import { tokenTypeToStyleTag } from './constants';

@@ -8,0 +9,0 @@

@@ -8,8 +8,5 @@ import { Diagnostic, linter } from '@codemirror/lint';

import type { LinterTask, LintWorker } from './lintWorker';
import WorkerURL from './lintWorker?worker&url';
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore ignore: https://v3.vitejs.dev/guide/features.html#import-with-query-suffixes
import WorkerURL from './lintWorker?url&worker';
const pool = workerpool.pool(WorkerURL as string, {
const pool = workerpool.pool(WorkerURL, {
minWorkers: 2,

@@ -16,0 +13,0 @@ workerOpts: { type: 'module' },

import { tokens } from '@neo4j-ndl/base';
import { expect, test } from 'vitest';
import { tokens as tokensCopy } from './ndlTokensCopy';

@@ -3,0 +4,0 @@

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc