Skip to content
Open
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
7 changes: 5 additions & 2 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [



{
"name": "Launch Edge",
"request": "launch",
Expand Down Expand Up @@ -48,15 +51,15 @@
]
},
{
"name": "markdown-loader",
"name": "markdown-loader constructor-injection.md",
"type": "node",
"request": "launch",

// Debug current file in VSCode
"program": "${workspaceFolder}/docs/src/markdown-loader.ts",
"cwd": "${workspaceFolder}/docs",
"args": [
"./registry.md"
"./constructor-injection.md"
],
/*
* Path to tsx binary
Expand Down
1 change: 1 addition & 0 deletions docs/_sidebar.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
- [Naming](advanced/name.md)
- [Caveats](caveats.md)
- [Testing](testing.md)
- [Writing Docs](writing-docs.md)
- [Examples](https://github.com/pbinj/pbj/tree/main/examples)
- [Ideas](ideas.md)
- [License](license.md)
20 changes: 18 additions & 2 deletions docs/advanced/caching.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,28 @@ PBinJ provides flexible caching capabilities through the `withCacheable` method
### Enable/Disable Caching

```typescript
import { context } from "@pbinj/pbj";
import { context, pbj } from "@pbinj/pbj";
class User {
constructor(public id: string, public name: string) {}
}
class UserRepository {
//...
findById(id: string) {
// Expensive operation
return new User(id, "John Doe");
}
}
class DatabaseService {
//...
constructor(private users = pbj(UserRepository)) {}
}

class UserService {
constructor(private db = pbj(DatabaseService)) {}

async getUser(id: string) {
// Expensive operation
return await db.users.findById(id);
return await this.db.users.findById(id);
}
}

Expand Down
33 changes: 29 additions & 4 deletions docs/advanced/service-events.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,14 @@ unsubscribe();
## Dynamic Service Collection

```typescript
import { pbjKey, context } from "@pbinj/pbj";

interface Plugin {
initialize(): void;
}

const pluginKey = pbjKey<Plugin>("plugin");

class PluginManager {
constructor(private plugins: Plugin[] = context.listOf(pluginKey)) {
/**
Expand All @@ -38,7 +46,9 @@ class PluginManager {
**/
context.onServiceAdded((...plugins) => {
for (const plugin of plugins) {
plugin.initialize();
if (plugin.hasTag(pluginKey)) {
plugin.invoke().initialize();
}
}
});
}
Expand Down Expand Up @@ -86,6 +96,8 @@ class RouterManager {
1. **Cleanup Subscriptions**: Always store and call the unsubscribe function when the listener is no longer needed:

```typescript
import { context } from "@pbinj/pbj";

class ServiceManager {
private unsubscribe?: () => void;

Expand All @@ -104,6 +116,12 @@ class ServiceManager {
2. **Efficient Updates**: Batch updates when handling multiple services:

```typescript
import { pbjKey, context } from "@pbinj/pbj";
interface Feature {
//...
}
const featureKey = pbjKey<Feature>("feature");

class FeatureManager {
private updateScheduled = false;

Expand All @@ -118,6 +136,9 @@ class FeatureManager {
}
});
}
updateFeatures(){
//...
}
}
```

Expand All @@ -133,7 +154,12 @@ class LoggerService {
}
const metricsKey = pbjKey<MetricsService>("metrics");
const loggingKey = pbjKey<LoggerService>("logging");

function updateMetrics() {
//...
}
function updateLoggers() {
//...
}
context.onServiceAdded((service) => {
if (service.hasTag(metricsKey)) {
updateMetrics();
Expand All @@ -150,5 +176,4 @@ context.onServiceAdded((service) => {
- The listener is called both for new services and when existing services change
- Use `hasTag()` to filter relevant service changes
- The event provides the `ServiceDescriptor`, not the service instance
- Multiple tags can be checked in a single listener
-
- Multiple tags can be checked in a single listener
23 changes: 16 additions & 7 deletions docs/advanced/tags.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,12 @@ class MetricsPlugin implements Plugin {
const pluginKey = pbjKey<Plugin>("plugin");

// Register services with tags
context.register(AuthPlugin).withTags("plugin");
context.register(LoggingPlugin).withTags("plugin");
context.register(MetricsPlugin).withTags("plugin");
context.register(AuthPlugin).withTags(pluginKey);
context.register(LoggingPlugin).withTags(pluginKey);
context.register(MetricsPlugin).withTags(pluginKey);

// Retrieve all tagged services
const plugins = context.listOf("plugin");
const plugins = context.listOf(pluginKey);
```

## Multiple Tags
Expand All @@ -36,15 +36,20 @@ const plugins = context.listOf("plugin");

import { pbjKey, context } from "@pbinj/pbj";
class UserService {
id(){
return 1;
}
//...
}
const userServiceKey = pbjKey<UserService>("user-service");
const idableKey = pbjKey<{id:number}>("core");

// Register with multiple tags
context.register(UserService).withTags("service", "user", "core");
context.register(UserService).withTags(userServiceKey, idableKey);

// Services can be retrieved by any of their tags
const services = context.listOf("service");
const userServices = context.listOf("user");
const services = context.listOf(idableKey);
const userServices = context.listOf(userServiceKey);
```

## Type-Safe Tags
Expand All @@ -58,11 +63,13 @@ interface Handler {
class AuthHandler implements Handler {
handle(request: Request) {
// Handle auth requests
return null as any;
}
}
class LoggingHandler implements Handler {
handle(request: Request) {
// Handle logging requests
return null as any;
}
}

Expand Down Expand Up @@ -150,13 +157,15 @@ class UserHandler implements RouteHandler {
method = "GET";
handle(req: Request) {
// Handle user requests
return null as any;
}
}
class AuthHandler implements RouteHandler {
path = "/auth";
method = "POST";
handle(req: Request) {
// Handle auth requests
return null as any;
}
}

Expand Down
Loading