forked from FINAKON/HelpProject
1. Initial Commit - a boiler plate code and POC to realize the concept of context sensitive help 2. Frontend code written in ReactJS 3. Backend code written in Java, Spring Boot Framework 4. Frontend Start: pre-requisites : node, npm npm run dev ==> to start the frontend vite server 5. Backend Start: pre-requisites : java, mvn mvn spring-boot:run ==> to start the backend server 6. Visit http://localhost:5173/ for basic demo of help, press F1 in textboxes 7. Visit http://localhost:5173/editor and enter "admin123" to add/modify texts. Happy Coding !!! Thank you, Bhargava.
361 lines
9.9 KiB
Markdown
361 lines
9.9 KiB
Markdown
# devlop
|
||
|
||
[![Build][build-badge]][build]
|
||
[![Coverage][coverage-badge]][coverage]
|
||
[![Downloads][downloads-badge]][downloads]
|
||
[![Size][size-badge]][size]
|
||
|
||
Some tools to make developing easier while not including code in production.
|
||
|
||
## Contents
|
||
|
||
* [What is this?](#what-is-this)
|
||
* [When should I use this?](#when-should-i-use-this)
|
||
* [Install](#install)
|
||
* [Use](#use)
|
||
* [API](#api)
|
||
* [`deprecate(fn, message[, code])`](#deprecatefn-message-code)
|
||
* [`equal(actual, expected[, message])`](#equalactual-expected-message)
|
||
* [`ok(value[, message])`](#okvalue-message)
|
||
* [`unreachable(message?)`](#unreachablemessage)
|
||
* [Types](#types)
|
||
* [Compatibility](#compatibility)
|
||
* [Security](#security)
|
||
* [Related](#related)
|
||
* [Contribute](#contribute)
|
||
* [License](#license)
|
||
|
||
## What is this?
|
||
|
||
This package lets you do things in development that are free in production.
|
||
It contains useful `assert` functions and a `deprecate` function that are
|
||
useful when developing JavaScript packages while being small in production.
|
||
|
||
If you know Rust, you might know how nice having a
|
||
[`debug_assert!`][rust-debug-assert] is.
|
||
This is that, and a bit more.
|
||
For more on why they’re nice, see
|
||
[“Rust’s Two Kinds of ‘Assert’ Make for Better Code”][rust-two-kinds]
|
||
|
||
## When should I use this?
|
||
|
||
Many JavaScript programs do not use assertions at all (perhaps because they’re
|
||
typed and so assume type safety) or include lots of code to throw errors when
|
||
users do weird things (weighing down production code).
|
||
This package hopes to improve the sitation by making assertions free and
|
||
deprecations cheap.
|
||
|
||
## Install
|
||
|
||
This package is [ESM only][esm].
|
||
In Node.js (version 16+), install with [npm][]:
|
||
|
||
```sh
|
||
npm install devlop
|
||
```
|
||
|
||
In Deno with [`esm.sh`][esmsh]:
|
||
|
||
```js
|
||
import {deprecate, equal, ok, unreachable} from 'https://esm.sh/devlop@1'
|
||
// For development code:
|
||
// import {deprecate, equal, ok} from 'https://esm.sh/devlop@1?conditions=development'
|
||
```
|
||
|
||
In browsers with [`esm.sh`][esmsh]:
|
||
|
||
```html
|
||
<script type="module">
|
||
import {deprecate, equal, ok, unreachable} from 'https://esm.sh/devlop@1?bundle'
|
||
// For development code:
|
||
// import {deprecate, equal, ok} from 'https://esm.sh/devlop@1?bundle&conditions=development'
|
||
</script>
|
||
```
|
||
|
||
## Use
|
||
|
||
Say we have a small ponyfill for the ES5 `String#includes` function.
|
||
It’s deprecated, because folks can use `String#includes` nowadays.
|
||
It’s nicely typed so users should be able to figure out what to pass but we
|
||
include assertions to show nicer errors when they get it wrong.
|
||
|
||
`example/string-includes.js`:
|
||
|
||
```js
|
||
import {deprecate, ok} from 'devlop'
|
||
|
||
export const stringIncludes = deprecate(
|
||
includes,
|
||
'Since ES5, please use `String#includes` itself.'
|
||
)
|
||
|
||
/**
|
||
* @deprecated
|
||
* Since ES5, please use `String#includes` itself.
|
||
* @param {string} value
|
||
* Value to search in.
|
||
* @param {string} search
|
||
* Value to search for.
|
||
* @param {number | undefined} [position=0]
|
||
* Position to search from (default: `0`).
|
||
* @returns {boolean}
|
||
* Whether the searched for value exists in the searched value after position.
|
||
*/
|
||
function includes(value, search, position) {
|
||
ok(typeof value === 'string', 'expected string for `value`')
|
||
ok(typeof search === 'string', 'expected string for `search`')
|
||
ok(position === undefined || typeof position === 'number', 'expected number')
|
||
ok(
|
||
position === undefined ||
|
||
(typeof position === 'number' &&
|
||
!(/* #__PURE__ */ Number.isNaN(position))),
|
||
'expected number'
|
||
)
|
||
// eslint-disable-next-line unicorn/prefer-includes
|
||
return value.indexOf(search, position || 0) !== -1
|
||
}
|
||
```
|
||
|
||
`example/index.js`:
|
||
|
||
```js
|
||
import {stringIncludes} from './example-includes.js'
|
||
|
||
console.log(stringIncludes('blue whale', 'dolphin')) //=> false
|
||
console.log(stringIncludes('blue whale', 'whale')) //=> true
|
||
```
|
||
|
||
Say we’d bundle that in development with [`esbuild`][esbuild] and check the
|
||
gzip size ([`gzip-size-cli`][gzip-size-cli]), we’d get 1.02 kB of code:
|
||
|
||
```sh
|
||
$ esbuild example/index.js --bundle --conditions=development --format=esm --minify --target=es2022 | gzip-size
|
||
1.02 kB
|
||
```
|
||
|
||
But because `devlop` is light in production we’d get:
|
||
|
||
```sh
|
||
$ esbuild example/index.js --bundle --format=esm --minify --target=es2022 | gzip-size
|
||
169 B
|
||
```
|
||
|
||
The bundle looks as follows:
|
||
|
||
```js
|
||
function u(n){return n}var r=u(c,"Since ES5, please use `String#includes` itself.");function c(n,t,e){return n.indexOf(t,e||0)!==-1}console.log(r("blue whale","dolphin"));console.log(r("blue whale","whale"));
|
||
```
|
||
|
||
It depends a bit on which bundler and minifier you use how small the code is:
|
||
esbuild keeps the unused message parameter to the `deprecate` function around
|
||
and does not know `Number.isNaN` can be dropped without a `/* #__PURE__ */`
|
||
annotation.
|
||
|
||
[`rollup`][rollup] with [`@rollup/plugin-node-resolve`][node-resolve]
|
||
and [`@rollup/plugin-terser`][terser] performs even better:
|
||
|
||
```sh
|
||
$ rollup example/index.js -p node-resolve -p terser | gzip-size
|
||
118 B
|
||
```
|
||
|
||
The bundle looks as follows:
|
||
|
||
```js
|
||
const l=function(l,e,o){return-1!==l.indexOf(e,o||0)};console.log(l("blue whale","dolphin")),console.log(l("blue whale","whale"));
|
||
```
|
||
|
||
Rollup doesn’t need the `/* #__PURE__ */` comment either!
|
||
|
||
## API
|
||
|
||
This package exports the identifiers [`deprecate`][api-deprecate],
|
||
[`equal`][api-equal], [`ok`][api-ok], and [`unreachable`][api-unreachable].
|
||
There is no default export.
|
||
|
||
The export map supports the [`development` condition][node-condition].
|
||
Run `node --conditions development module.js` to get dev code.
|
||
Without this condition, no-ops are loaded.
|
||
|
||
### `deprecate(fn, message[, code])`
|
||
|
||
Wrap a function or class to show a deprecation message when first called.
|
||
|
||
> 👉 **Important**: only shows a message when the `development` condition is
|
||
> used, does nothing in production.
|
||
|
||
When the resulting wrapped `fn` is called, emits a warning once to
|
||
`console.error` (`stderr`).
|
||
If a code is given, one warning message will be emitted in total per code.
|
||
|
||
###### Parameters
|
||
|
||
* `fn` (`Function`)
|
||
— function or class
|
||
* `message` (`string`)
|
||
— message explaining deprecation
|
||
* `code` (`string`, optional)
|
||
— deprecation identifier (optional); deprecation messages will be generated
|
||
only once per code
|
||
|
||
###### Returns
|
||
|
||
Wrapped `fn`.
|
||
|
||
### `equal(actual, expected[, message])`
|
||
|
||
Assert deep strict equivalence.
|
||
|
||
> 👉 **Important**: only asserts when the `development` condition is used, does
|
||
> nothing in production.
|
||
|
||
###### Parameters
|
||
|
||
* `actual` (`unknown`)
|
||
— value
|
||
* `expected` (`unknown`)
|
||
— baseline
|
||
* `message` (`Error` or `string`, default: `'Expected values to be deeply
|
||
equal'`)
|
||
— message for assertion error
|
||
|
||
###### Returns
|
||
|
||
Nothing (`undefined`).
|
||
|
||
###### Throws
|
||
|
||
Throws (`AssertionError`) when `actual` is not deep strict equal to `expected`.
|
||
|
||
### `ok(value[, message])`
|
||
|
||
Assert if `value` is truthy.
|
||
|
||
> 👉 **Important**: only asserts when the `development` condition is used, does
|
||
> nothing in production.
|
||
|
||
###### Parameters
|
||
|
||
* `actual` (`unknown`)
|
||
— value to assert
|
||
* `message` (`Error` or `string`, default: `'Expected value to be truthy'`)
|
||
— message for assertion error
|
||
|
||
###### Returns
|
||
|
||
Nothing (`undefined`).
|
||
|
||
###### Throws
|
||
|
||
Throws (`AssertionError`) when `value` is falsey.
|
||
|
||
### `unreachable(message?)`
|
||
|
||
Assert that a code path never happens.
|
||
|
||
> 👉 **Important**: only asserts when the `development` condition is used,
|
||
> does nothing in production.
|
||
|
||
###### Parameters
|
||
|
||
* `message` (`Error` or `string`, default: `'Unreachable'`)
|
||
— message for assertion error
|
||
|
||
###### Returns
|
||
|
||
Never (`never`).
|
||
|
||
###### Throws
|
||
|
||
Throws (`AssertionError`), always.
|
||
|
||
## Types
|
||
|
||
This package is fully typed with [TypeScript][].
|
||
It exports no additional types.
|
||
|
||
## Compatibility
|
||
|
||
This project is compatible with maintained versions of Node.js.
|
||
|
||
When we cut a new major release, we drop support for unmaintained versions of
|
||
Node.
|
||
This means we try to keep the current release line, `devlop@^1`,
|
||
compatible with Node.js 16.
|
||
|
||
## Security
|
||
|
||
This package is safe.
|
||
|
||
## Related
|
||
|
||
* [`babel-plugin-unassert`](https://github.com/unassert-js/babel-plugin-unassert)
|
||
— encourage reliable programming with assertions while compiling them away
|
||
in production (can remove arbitrary `assert` modules, works regardless of
|
||
conditions, so has to be configured by the end user)
|
||
|
||
## Contribute
|
||
|
||
Yes please!
|
||
See [How to Contribute to Open Source][contribute].
|
||
|
||
## License
|
||
|
||
[MIT][license] © [Titus Wormer][author]
|
||
|
||
<!-- Definition -->
|
||
|
||
[build-badge]: https://github.com/wooorm/devlop/workflows/main/badge.svg
|
||
|
||
[build]: https://github.com/wooorm/devlop/actions
|
||
|
||
[coverage-badge]: https://img.shields.io/codecov/c/github/wooorm/devlop.svg
|
||
|
||
[coverage]: https://codecov.io/github/wooorm/devlop
|
||
|
||
[downloads-badge]: https://img.shields.io/npm/dm/devlop.svg
|
||
|
||
[downloads]: https://www.npmjs.com/package/devlop
|
||
|
||
[size-badge]: https://img.shields.io/badge/dynamic/json?label=minzipped%20size&query=$.size.compressedSize&url=https://deno.bundlejs.com/?q=devlop
|
||
|
||
[size]: https://bundlejs.com/?q=devlop
|
||
|
||
[npm]: https://docs.npmjs.com/cli/install
|
||
|
||
[esmsh]: https://esm.sh
|
||
|
||
[license]: license
|
||
|
||
[author]: https://wooorm.com
|
||
|
||
[esm]: https://gist.github.com/sindresorhus/a39789f98801d908bbc7ff3ecc99d99c
|
||
|
||
[typescript]: https://www.typescriptlang.org
|
||
|
||
[contribute]: https://opensource.guide/how-to-contribute/
|
||
|
||
[node-condition]: https://nodejs.org/api/packages.html#packages_resolving_user_conditions
|
||
|
||
[rust-debug-assert]: https://doc.rust-lang.org/std/macro.debug_assert.html
|
||
|
||
[rust-two-kinds]: https://tratt.net/laurie/blog/2023/rusts_two_kinds_of_assert_make_for_better_code.html
|
||
|
||
[esbuild]: https://esbuild.github.io
|
||
|
||
[gzip-size-cli]: https://github.com/sindresorhus/gzip-size-cli/tree/main
|
||
|
||
[rollup]: https://rollupjs.org
|
||
|
||
[node-resolve]: https://github.com/rollup/plugins/tree/master/packages/node-resolve
|
||
|
||
[terser]: https://github.com/rollup/plugins/tree/master/packages/terser#readme
|
||
|
||
[api-deprecate]: #deprecatefn-message-code
|
||
|
||
[api-equal]: #equalactual-expected-message
|
||
|
||
[api-ok]: #okvalue-message
|
||
|
||
[api-unreachable]: #unreachablemessage
|