Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(repository): delete operation in hasOne relation and example hasOne #2347

Closed
wants to merge 17 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/stale.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ exemptLabels:
- critical
- p1
- major
- good first issue
# Label to use when marking an issue as stale
staleLabel: stale
# Comment to post when marking an issue as stale. Set to `false` to disable
Expand Down
11 changes: 11 additions & 0 deletions benchmark/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,17 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.

## [1.1.10](https://github.com/strongloop/loopback-next/compare/@loopback/[email protected]...@loopback/[email protected]) (2019-02-08)


### Bug Fixes

* **benchmark:** set TypeScript's rootDir to src ([51cba45](https://github.com/strongloop/loopback-next/commit/51cba45))





## [1.1.9](https://github.com/strongloop/loopback-next/compare/@loopback/[email protected]...@loopback/[email protected]) (2019-01-28)

**Note:** Version bump only for package @loopback/benchmark
Expand Down
16 changes: 8 additions & 8 deletions benchmark/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@loopback/benchmark",
"version": "1.1.9",
"version": "1.1.10",
"private": true,
"description": "Benchmarks measuring performance of our framework.",
"keywords": [
Expand Down Expand Up @@ -35,11 +35,11 @@
"!*/__tests__"
],
"dependencies": {
"@loopback/example-todo": "^1.4.2",
"@loopback/openapi-spec-builder": "^1.0.5",
"@loopback/rest": "^1.5.4",
"@loopback/example-todo": "^1.4.3",
"@loopback/openapi-spec-builder": "^1.0.6",
"@loopback/rest": "^1.5.5",
"@types/byline": "^4.2.31",
"@types/debug": "^0.0.31",
"@types/debug": "^4.1.0",
"@types/p-event": "^1.3.0",
"@types/request-promise-native": "^1.0.15",
"autocannon": "^3.0.0",
Expand All @@ -50,12 +50,12 @@
"request-promise-native": "^1.0.5"
},
"devDependencies": {
"@loopback/build": "^1.2.1",
"@loopback/testlab": "^1.0.5",
"@loopback/build": "^1.3.0",
"@loopback/testlab": "^1.0.6",
"@types/mocha": "^5.0.0",
"@types/node": "^10.11.2",
"mocha": "^5.1.1",
"p-event": "^2.1.0",
"p-event": "^2.3.1",
"source-map-support": "^0.5.5"
}
}
13 changes: 13 additions & 0 deletions docs/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,19 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.

## [1.7.3](https://github.com/strongloop/loopback-next/compare/@loopback/[email protected]...@loopback/[email protected]) (2019-02-08)


### Bug Fixes

* **docs:** remove .ts from imports ([c601c4c](https://github.com/strongloop/loopback-next/commit/c601c4c))
* **docs:** update link in todo-tutorial-geocoding-service ([e6a8d73](https://github.com/strongloop/loopback-next/commit/e6a8d73))
* **docs:** update test paths to `src/__tests__` ([75731f9](https://github.com/strongloop/loopback-next/commit/75731f9))





## [1.7.2](https://github.com/strongloop/loopback-next/compare/@loopback/[email protected]...@loopback/[email protected]) (2019-01-28)

**Note:** Version bump only for package @loopback/docs
Expand Down
4 changes: 2 additions & 2 deletions docs/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@loopback/docs",
"version": "1.7.2",
"version": "1.7.3",
"description": "Documentation for LoopBack 4",
"homepage": "https://github.com/strongloop/loopback-next/tree/master/docs",
"author": {
Expand All @@ -22,7 +22,7 @@
"clean": "lb-clean loopback-docs*.tgz package api-docs site/readmes"
},
"devDependencies": {
"@loopback/build": "^1.2.1"
"@loopback/build": "^1.3.0"
},
"publishConfig": {
"access": "public"
Expand Down
192 changes: 192 additions & 0 deletions docs/site/Context.md
Original file line number Diff line number Diff line change
Expand Up @@ -229,3 +229,195 @@ class HelloController {
These "sugar" decorators allow you to quickly build up your application without
having to code up all the additional logic by simply giving LoopBack hints (in
the form of metadata) to your intent.

## Context events

The `Context` emits the following events:

- `bind`: Emitted when a new binding is added to the context.
- binding: the newly added binding object
- context: Owner context of the binding object
- `unbind`: Emitted when an existing binding is removed from the context
- binding: the newly removed binding object
- context: Owner context of the binding object
- `error`: Emitted when an observer throws an error during the notification
process
- err: the error object thrown

When an existing binding key is replaced with a new one, an `unbind` event is
emitted for the existing binding followed by a `bind` event for the new binding.

If a context has a parent, binding events from the parent are re-emitted on the
context when the binding key does not exist within the current context.

## Context observers

Bindings can be added or removed to a context object. With emitted context
events, we can add listeners to a context object to be invoked when bindings
come and go. There are a few caveats associated with that:

1. The binding object might not be fully configured when a `bind` event is
emitted.

For example:

```ts
const ctx = new Context();
ctx
.bind('foo')
.to('foo-value')
.tag('foo-tag');
ctx.on('bind', binding => {
console.log(binding.tagNames); // returns an empty array `[]`
});
```

The context object emits a `bind` event when `ctx.bind` method is called. It
does not control the fluent apis `.to('foo-value').tag('foo-tag')`, which
happens on the newly created binding object. As a result, the `bind` event
listener receives a binding object which only has the binding key populated.

A workaround is to create the binding first before add it to a context:

```ts
const ctx = new Context();
const binding = Binding.create('foo')
.to('foo-value')
.tag('foo-tag');
ctx.add(binding);
ctx.on('bind', binding => {
console.log(binding.tagMap); // returns `['foo-tag']`
});
```

2. It's hard for event listeners to perform asynchronous operations.

To make it easy to support asynchronous event processing, we introduce
`ContextObserver` and corresponding APIs on `Context`:

1. `ContextObserverFn` type and `ContextObserver` interface

```ts
/**
* Listen on `bind`, `unbind`, or other events
* @param eventType Context event type
* @param binding The binding as event source
* @param context Context object for the binding event
*/
export type ContextObserverFn = (
eventType: ContextEventType,
binding: Readonly<Binding<unknown>>,
context: Context,
) => ValueOrPromise<void>;

/**
* Observers of context bind/unbind events
*/
export interface ContextObserver {
/**
* An optional filter function to match bindings. If not present, the listener
* will be notified of all binding events.
*/
filter?: BindingFilter;

/**
* Listen on `bind`, `unbind`, or other events
* @param eventType Context event type
* @param binding The binding as event source
*/
observe: ContextObserverFn;
}

/**
* Context event observer type - An instance of `ContextObserver` or a function
*/
export type ContextEventObserver = ContextObserver | ContextObserverFn;
```

If `filter` is not required, we can simply use `ContextObserverFn`.

2. Context APIs

- `subscribe(observer: ContextEventObserver)`

Add a context event observer to the context chain, including its ancestors

- `unsubscribe(observer: ContextEventObserver)`

Remove the context event observer from the context chain

- `close()`

Close the context and release references to other objects in the context
chain. Please note a child context registers event listeners with its parent
context. As a result, the `close` method must be called to avoid memory leak
if the child context is to be recycled.

To react on context events asynchronously, we need to implement the
`ContextObserver` interface or provide a `ContextObserverFn` and register it
with the context.

For example:

```ts
const app = new Context('app');
server = new Context(app, 'server');

const observer: ContextObserver = {
// Only interested in bindings tagged with `foo`
filter: binding => binding.tagMap.foo != null,

observe(event: ContextEventType, binding: Readonly<Binding<unknown>>) {
if (event === 'bind') {
console.log('bind: %s', binding.key);
// ... perform async operation
} else if (event === 'unbind') {
console.log('unbind: %s', binding.key);
// ... perform async operation
}
},
};

server.subscribe(observer);
server
.bind('foo-server')
.to('foo-value')
.tag('foo');
app
.bind('foo-app')
.to('foo-value')
.tag('foo');

// The following messages will be printed:
// bind: foo-server
// bind: foo-app
```

Please note when an observer subscribes to a context, it will be registered with
all contexts on the chain. In the example above, the observer is added to both
`server` and `app` contexts so that it can be notified when bindings are added
or removed from any of the context on the chain.

- Observers are called in the next turn of
[Promise micro-task queue](https://jsblog.insiderattack.net/promises-next-ticks-and-immediates-nodejs-event-loop-part-3-9226cbe7a6aa)

- When there are multiple async observers registered, they are notified in
series for an event.

- When multiple binding events are emitted in the same event loop tick and there
are async observers registered, such events are queued and observers are
notified by the order of events.

### Observer error handling

It's recommended that `ContextEventObserver` implementations should not throw
errors in their code. Errors thrown by context event observers are reported as
follows over the context chain.

1. Check if the current context object has `error` listeners, if yes, emit an
`error` event on the context and we're done. if not, try its parent context
by repeating step 1.

2. If no context object of the chain has `error` listeners, emit an `error`
event on the current context. As a result, the process exits abnormally. See
https://nodejs.org/api/events.html#events_error_events for more details.
18 changes: 0 additions & 18 deletions docs/site/Controllers.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,24 +17,6 @@ processed input and abstractions of backend services / databases.

This page will only cover a `Controller`'s usage with REST APIs.

### Review questions

{% include content/tbd.html %}

Simplest possible example of a Controller

- `app.controller()`
- a few methods
- no usage of `@api`

How to create a basic `Controller` (beyond the hello world)

- Using DI (`@inject`)
- Using decorators (eg. `@authenticate`)
- Defining routes via sugar annoations (`@get`, `@post`)
- Errors
- Using `async` / `await` and `Promise`s

## Operations

In the Operation example in [Routes](Routes.md), the `greet()` operation was
Expand Down
2 changes: 1 addition & 1 deletion docs/site/Crafting-LoopBack-4.md
Original file line number Diff line number Diff line change
Expand Up @@ -473,7 +473,7 @@ There are several key pillars to make extensibility a reality for LoopBack 4.
- [Context](Context.md), the IoC container to manage services
- [Dependency injection](Dependency-injection.md) to facilitate composition
- [Decorators](Decorators.md) to supply metadata using annotations
- [Component](Component.md) as the packaging model to bundle extensions
- [Component](Using-components.md) as the packaging model to bundle extensions

Please check out [Extending LoopBack 4](Extending-LoopBack-4.md).

Expand Down
2 changes: 1 addition & 1 deletion docs/site/Repositories.md
Original file line number Diff line number Diff line change
Expand Up @@ -300,7 +300,7 @@ application.
## Access KeyValue Stores

We can now access key-value stores such as [Redis](https://redis.io/) using the
[KeyValueRepository]((https://github.com/strongloop/loopback-next/blob/master/packages/repository/src/repositories/kv.repository.ts).
[KeyValueRepository](https://github.com/strongloop/loopback-next/blob/master/packages/repository/src/repositories/kv.repository.ts).

### Define a KeyValue Datasource

Expand Down
8 changes: 8 additions & 0 deletions examples/hello-world/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,14 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.

## [1.1.3](https://github.com/strongloop/loopback-next/compare/@loopback/[email protected]...@loopback/[email protected]) (2019-02-08)

**Note:** Version bump only for package @loopback/example-hello-world





## [1.1.2](https://github.com/strongloop/loopback-next/compare/@loopback/[email protected]...@loopback/[email protected]) (2019-01-28)

**Note:** Version bump only for package @loopback/example-hello-world
Expand Down
10 changes: 5 additions & 5 deletions examples/hello-world/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@loopback/example-hello-world",
"version": "1.1.2",
"version": "1.1.3",
"description": "A simple hello-world Application using LoopBack 4",
"main": "index.js",
"engines": {
Expand Down Expand Up @@ -36,12 +36,12 @@
},
"license": "MIT",
"dependencies": {
"@loopback/core": "^1.1.5",
"@loopback/rest": "^1.5.4"
"@loopback/core": "^1.1.6",
"@loopback/rest": "^1.5.5"
},
"devDependencies": {
"@loopback/build": "^1.2.1",
"@loopback/testlab": "^1.0.5",
"@loopback/build": "^1.3.0",
"@loopback/testlab": "^1.0.6",
"@loopback/tslint-config": "^2.0.0",
"@types/node": "^10.11.2",
"tslint": "^5.12.0",
Expand Down
8 changes: 8 additions & 0 deletions examples/log-extension/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,14 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.

## [1.1.3](https://github.com/strongloop/loopback-next/compare/@loopback/[email protected]...@loopback/[email protected]) (2019-02-08)

**Note:** Version bump only for package @loopback/example-log-extension





## [1.1.2](https://github.com/strongloop/loopback-next/compare/@loopback/[email protected]...@loopback/[email protected]) (2019-01-28)

**Note:** Version bump only for package @loopback/example-log-extension
Expand Down
Loading